Last Comment Bug 159483 - cert name matching: RFC 2818 vs. backwards compatibility (wildcards)
: cert name matching: RFC 2818 vs. backwards compatibility (wildcards)
Status: RESOLVED FIXED
[sg:want]
: fixed1.9.1, verified1.9.0.13, verified1.9.0.14
Product: NSS
Classification: Components
Component: Libraries (show other bugs)
: 3.4
: All All
: P1 normal with 6 votes (vote)
: 3.12.3
Assigned To: Nelson Bolyard (seldom reads bugmail)
:
Mentors:
https://mail.netidentity.com.cust.hos...
: 194285 389295 438322 501862 560476 (view as bug list)
Depends on: 500495
Blocks:
  Show dependency treegraph
 
Reported: 2002-07-25 19:49 PDT by Nelson Bolyard (seldom reads bugmail)
Modified: 2014-06-03 10:07 PDT (History)
38 users (show)
reed: wanted1.9.2?
mbeltzner: blocking1.9.1+
reed: wanted1.9.1?
mbeltzner: blocking1.9-
mbeltzner: wanted1.9+
samuel.sidler+old: blocking1.9.0.13+
dveditz: blocking1.9.0.14+
dveditz: wanted1.9.0.x+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---


Attachments
Minimal patch (addresses item b in comment 6) (3.44 KB, patch)
2007-11-10 07:36 PST, Kaspar Brand
no flags Details | Diff | Review
Test program (for illustration purposes only) (3.42 KB, patch)
2007-11-10 07:39 PST, Kaspar Brand
no flags Details | Diff | Review
Alternative patch for (more restrictive) wildcard matching (2.32 KB, patch)
2007-11-14 07:53 PST, Kaspar Brand
no flags Details | Diff | Review
Alternative patch for wildcard matching, incorporating suggestion from comment 25 (2.58 KB, patch)
2007-11-19 10:16 PST, Kaspar Brand
no flags Details | Diff | Review
Alternative patch for wildcard matching v3, addressing review comments (2.46 KB, patch)
2007-11-30 23:31 PST, Kaspar Brand
nelson: review+
Details | Diff | Review
Updated test program (for illustration purposes only), incorporating code from patch v3 [cf. comment 34] (3.94 KB, patch)
2007-11-30 23:35 PST, Kaspar Brand
no flags Details | Diff | Review
alternative patch v4 - preserve old code with environment variable (2.53 KB, patch)
2009-03-10 16:29 PDT, Nelson Bolyard (seldom reads bugmail)
no flags Details | Diff | Review
patch v5 - don't call it regex (2.92 KB, patch)
2009-03-11 13:07 PDT, Nelson Bolyard (seldom reads bugmail)
wtc: superreview+
Details | Diff | Review
3.0.12 vs 3.0.13 (87.93 KB, image/png)
2009-07-31 21:24 PDT, juan becerra [:juanb]
no flags Details

Description Nelson Bolyard (seldom reads bugmail) 2002-07-25 19:49:19 PDT
RFC 2818 and 2459 give the rules for cert name matching between an https 
(SSL) server cert and the hostname present in the sought URI.  

NSS's function CERT_VerifyCertName, which does the server cert name matching,
has its own rules, rules that declare some name matches in circumstances 
where the RFCs would not.  Changing function CERT_VerifyCertName to follow
the RFCs exactly will break backwards compatibility.  It is possible that
some customers (users of mozilla and/or netscape browsers) depend on the 
behavior that would be changed/removed if function CERT_VerifyCertName 
followed the RFC exactly.  So, a decision needs to be made about what rules
function CERT_VerifyCertName will follow in the future.  

The scope of this bug is limited to the matching of the URI hostname to 
any of the names found in the cert.  The fact that function CERT_VerifyCertName
does not presently examine Subject Alternative Names is the subject of bug 
103752, and is outside the scope of this bug.  When bug 103752 is fixed,
function CERT_VerifyCertName will examine each of the Subject Alternative
Names as well as the Subject name's common name and compare them to the URI
name.  At issue in this bug are the rules used in each of those comparisons.

Here is how function CERT_VerifyCertName compares the hostname in the URI 
(call it "hn") and the host name from the cert (call it "cn"):

Step 1.  If hn does not contain a "dot", and cn does contain a dot, then 
        truncate cn at the left most dot.

        e.g. if hn is "www" and cn is "www.foo.com", truncate cn to be "www".

Step 2.  If "cn" is a regular expression (e.g. has wild card characters,
         etc.) then test whether hn matches the regular expression in cn.  
         If so, the cert name matches, if not it is a mismatch error. 
         Either way, Stop here if cn is a regular expression.

Step 3.  "cn" is not a regular expression.  compare the hn and cn strings.
        if they match, the cert name matches, stop.  

Step 4.  If hn contained a dot, compare the string to the right of the 
        leftmost dot in hn (that is, the domain part of hn) with the 
        string cn.  If they match, the cert name is considered a match, stop.

        examples:
         if hn is "www.foo.bar" and cn is "foo.bar", they will match.
         if hn is "www.xxx.foo.bar" and cn is "foo.bar", they will not match.

Step 5. The cert name is a mismatch.  stop.

Of these, steps 1 and 4 are behavior that would cease if the function was
made to follow the RFC.  

Step 1 is done essentially to permit the use of non fully qualified domain 
names in https links in intranet environments where there is often
a great desire to omit the common and constant domain portion from URLs.
E.g. employees often want to be able to type in https://mail/ instead of 
https://mail.my.company.domain.com/  and step 1 permits this to work.

Many companies have historically wanted to avoid the cost and administrative 
burden of getting a separate cert for every machine.  They wanted a single 
cert & private key that could be used on multiple intranet servers.  
Some popular CAs refuse to issue certs with wildcard characters, so step 4 
provides an alternative way for a company to get a cert that is valid for all 
servers in a domain (but not for servers in subdomains of that domain).  

It is unknown how many companies (if any) presently depend on the features
of step 1 and step 4.  Assuming that no other browser supports those rules,
and that no companies use any one brand of browser exclusively, it may be 
painless to remove those steps.

Your comments are invited.
Comment 1 Wan-Teh Chang 2002-07-25 22:33:27 PDT
Step 1 seems useful to me.  I found that IE doesn't
do step 1 and it is inconvenient to have to type
fully qualified domain names in https URLs in an
intranet.

Step 4 seems overly relaxed.  I can't find a test
case for step 4, so I don't know if IE supports it.

In any case, I am afraid that we need to be
compatible with these extensions.
Comment 2 Nelson Bolyard (seldom reads bugmail) 2003-03-12 15:38:00 PST
*** Bug 194285 has been marked as a duplicate of this bug. ***
Comment 3 Nelson Bolyard (seldom reads bugmail) 2003-03-12 15:48:51 PST
Note that RFC 2818 says: 

> Status of this Memo
>
>   This memo provides information for the Internet community.  It does
>   not specify an Internet standard of any kind.  

NSS attempts to ensure that the set of certs that it matches to the host 
name in a URI is at least as great as the set specified in RFC 2818, but 
strict adherence to RFC 2818 is not an absolute goal, given that 2818 is
not an Internet standard of any kind.  

There are a number of ways in which NSS matches certificates more broadly 
than RFC 2818 suggests.  Bug 194285 notes another way (in addition to 
those already mentioned above).  NSS treats host names in certs as unix 
regular expressions, where * matches all strings.  RFC 2818 says:

>  [...] Names may contain the wildcard
>  character * which is considered to match any single domain name
>  component or component fragment. E.g., *.a.com matches foo.a.com but
>  not bar.foo.a.com. [...]
Comment 4 Nelson Bolyard (seldom reads bugmail) 2003-05-12 17:10:43 PDT
P3.
Comment 5 Jo Hermans 2006-10-08 01:08:20 PDT
is this still being worked at ?
Comment 6 Nelson Bolyard (seldom reads bugmail) 2006-10-09 23:35:11 PDT
Perhaps this bug can be RESOLVED as WORKSFORME.
Since it was filed, several changes were made to the comparison of
host names in URLs and host names in certs.  IIRC, steps 1 and 4 were 
determined to be vulnerabilities, and were eliminated.  
Bug 103752 was implemented and SANs are now supported per RFC 2818.

There are some issues that remain that get occasional grumbles, and 
are probably the subjects of other bugs.  They are:

a) NSS ignores a cert's subject CommonNames if/when there are DNS names
in the subject Alternate Names extension.  This is due to a very literal
reading of RFC 2818.  IE will match names from either place, even when
DNS names are present in the SAN.

b) (as reported in comment 0), NSS matches a "*" to any characters, 
whereas RFC 2818 suggests it should not match a ".".  We do this for
backwards compatibility with NSS's original spec on pattern matching.

c) NSS accepts at most one Subject Common Name, the most specific one.
This is specified in RFC 2818, but some CAs think that multiple CNs
should be allowed.  

Of these issues, Perhaps I could be persuaded to change the first two.
Comment 7 Bernhard Fröhlich 2006-10-13 04:17:04 PDT
(In reply to comment #6)
[...]
> b) (as reported in comment 0), NSS matches a "*" to any characters, 
> whereas RFC 2818 suggests it should not match a ".".  We do this for
> backwards compatibility with NSS's original spec on pattern matching.
[...] 
> Of these issues, Perhaps I could be persuaded to change the first two.

How could I help to persuade you to fix b)? Now please don't say "Threaten to send me explosive devices"...
Comment 8 Nelson Bolyard (seldom reads bugmail) 2006-10-13 16:43:33 PDT
Explosives?  Heavens, no!  
Send pictures of dead American presidents on green paper!  :)
Comment 9 Kaspar Brand 2006-10-14 03:43:55 PDT
(In reply to comment #6)
> b) (as reported in comment 0), NSS matches a "*" to any characters, 
> whereas RFC 2818 suggests it should not match a ".".  We do this for
> backwards compatibility with NSS's original spec on pattern matching.

Count me in as another (strong) proponent of changing this - for two reasons:

1) most other implementations I've encountered so far (MSIE/Schannel,
   Opera, Safari/libsecurity_apple_x509_tp, Konqueror/KDE, GnuTLS)
   apply a more restrictive matching than NSS (although they differ in
   their specific behavior, but at least they do not allow using certs
   with subjects like CN=*)

2) there are at least two other RFCs (besides 2818) which stipulate the more
   restrictive form of wildcard matching, and these are actually on the
   "Standards Track":

   a) RFC 2595 ("Using TLS with IMAP, POP3 and ACAP", June 1999) says
      in 2.4., "Server Identity Check":

      - A "*" wildcard character MAY be used as the left-most name
        component in the certificate.  For example, *.example.com would
        match a.example.com, foo.example.com, etc. but would not match
        example.com.

   b) RFC 4513 ("Lightweight Directory Access Protocol (LDAP):
      Authentication Methods and Security Mechanisms", June 2006) states
      under 3.1.3.1., "Comparison of DNS Names":

      The '*' (ASCII 42) wildcard character is allowed in subjectAltName
      values of type dNSName, and then only as the left-most (least
      significant) DNS label in that value.  This wildcard matches any
      left-most DNS label in the server name.  That is, the subject
      *.example.com matches the server names a.example.com and
      b.example.com, but does not match example.com or a.b.example.com.
Comment 10 Nelson Bolyard (seldom reads bugmail) 2007-07-23 23:28:45 PDT
*** Bug 389295 has been marked as a duplicate of this bug. ***
Comment 11 Nelson Bolyard (seldom reads bugmail) 2007-07-23 23:40:50 PDT
Note that the passages quoted above from RFC 2595 and RFC 4513 specify 
different restrictions on wildcard matching.  NSS already does what the
quoted text from RFC 2595 says.  

NSS has had this behavior since Netscape Navigator 3, if not before then.

Once upon a time, the Netscape & Mozilla browsers were well entrenched 
in corporate intranets.  Intranet sysadmins LIKE the present wildcard
behavior, which means they can get by with fewer certs.  So far, we've 
resisted breaking compatibility for them.  Changing it will mean that
sysadmins will need to get new certs for every subdomain.

If you really hate it, identify a vulnerability that is bad enough to 
warrant changing it, but not bad enough to warrant discontinuing the 
use of wildcards altogether (as many have proposed).  
Comment 12 Wan-Teh Chang 2007-07-24 07:45:34 PDT
The wildcard matching specified in RFC 4513 seems reasonable
to me.  But we need to consider the risk of breaking backward
compatibility.
Comment 13 Kaspar Brand 2007-07-24 10:59:57 PDT
(In reply to comment #11)
> Note that the passages quoted above from RFC 2595 and RFC 4513 specify 
> different restrictions on wildcard matching.

They don't say exactly the same thing, yes, but other than that, I don't think they contradict each other - or do they?

> NSS already does what the quoted text from RFC 2595 says.

Not in my understanding of that sentence, actually - if it says 'A "*" wildcard character MAY be used as the left-most name component in the certificate', then that does not allow for things like

   www.*
   *.*.example.org
   www.*.example.org
   *.*

on the other hand, I believe... all these have a "*" which is *not* in the left-most component. However, NSS will happily accept these, which leads to issues such as the one reported in bug 285361 (which has been resolved with WONTFIX, I know - but I disagree with that assessment to a certain degree... even if that single CN=* certificate came from a good guy, originally, the security of your browser might depend on the security of the host configured with this certificate, from then on - if an attacker manages to steal this particular private key, he can play MITM for you for any site).

Also, when considering how host name matching is currently done in NSS, I don't think it makes any real sense to support patterns like these in a host name:

> * o * matches anything
> * o ? matches one character
> * o \ will escape a special character
> * o $ matches the end of the string
> * o [abc] matches one occurence of a, b, or c. The only character that needs
> *         to be escaped in this is ], all others are not special.
> * o [a-z] matches any character between a and z
> * o [^az] matches any character except a or z
> * o ~ followed by another shell expression will remove any pattern
> *     matching the shell expression from the match list
> * o (foo|bar) will match either the substring foo, or the substring bar.
> *             These can be shell expressions as well.

(http://lxr.mozilla.org/mozilla/source/security/nss/lib/util/portreg.h#44)

While this allows you playing funny tricks with certs and host names like

   *~.biz$              (any host not in the .biz TLD)
   (|www.)example.org   (www.example.org and example.org)
   [^w]*                (any host name which doesn't begin with "w")

this might be cool for doing experiments (yes, they do work in Firefox e.g.!), but it's probably not really intended behavior...

Let me encourage you again to drop that kind of pattern matching for host names from NSS, and implement wildcard matching in the spirit of RFCs 2595, 2818 and 4513.
Comment 14 Nils Toedtmann 2007-11-03 07:10:41 PDT
I fully agree to the former poster:

(1) Matching the dot with "*" is a violation of RFC 2818 (HTTPS), and other RFCs regarding TLS-protocols (IMAPS/LDAPS/...) are not less restrictive.

(2) Matching anything with top-level-wildcard "CN=*" is bad practice.

(3) Not showing "subjectAltName:dNSName=*" in the standard vertificate view but matching it with any domain name is VERY BAD PRACTICE (although replacing "CN",  "subjectAltName" is hidden in the "details", see bug #238142).

This is a security issue and should be fixed.
Comment 15 Wan-Teh Chang 2007-11-03 17:55:43 PDT
If anyone would like to write a patch, the starting point is the
CERT_VerifyCertName function:
http://lxr.mozilla.org/security/ident?i=CERT_VerifyCertName

The actual matching is done in the cert_TestHostName function:
http://lxr.mozilla.org/security/ident?i=cert_TestHostName

which delegates pattern matching to the PORT_RegExpCaseSearch
function:
http://lxr.mozilla.org/security/ident?i=PORT_RegExpCaseSearch

Note on the backward compatibility of exported NSS functions:

Since PORT_RegExpCaseSearch will be exported for the first time
in the upcoming NSS 3.12 release, if a patch for this bug is accepted
before NSS 3.12 is released, we can change PORT_RegExpCaseSearch
directly.  Otherwise, we will need to add a new function that
does the RFC-compliant pattern matching.

Alternatively, we can move nss/lib/util/portreg.{h,c} to
nss/lib/certdb so that the PORT_RegExpCaseSearch doesn't need
to be exported from the new libnssutil3.so shared library in
NSS 3.12.
Comment 16 Kaspar Brand 2007-11-10 07:36:30 PST
Created attachment 288137 [details] [diff] [review]
Minimal patch (addresses item b in comment 6)

(In reply to comment #15)
> If anyone would like to write a patch,

Here's a patch which I would call "minimal" in the sense that it tries to maintain backward compatibility as far as possible (i.e. it still supports all those patterns mentioned in comment 13).

Specifically, the patch changes these two things:

- in cert_TestHostName(), it makes sure that the '*' character is only considered for wildcard matching if it occurs in the leftmost DNS name component (otherwise, it's just compared as a literal character)

- modifies _shexp_match() to not match the '.' character when using doing wildcard matching with '*'

I will also attach a short test program I used to verify the results of the new code. It's a bit more liberal than what RFCs 2595 and 4513 suggest ("THE left-most name component" implies that things like "www*.example.com", "w*w.example.com", "w*w**w.example.com" aren't valid wildcard expressions), but I don't think it hurts if we allow them for the time being.

> Alternatively, we can move nss/lib/util/portreg.{h,c} to
> nss/lib/certdb so that the PORT_RegExpCaseSearch doesn't need
> to be exported from the new libnssutil3.so shared library in
> NSS 3.12.

I would warmly recommend that - and also change the names of the three PORT_RegExpXXX() wrapper functions at that time... they are quite big misnomers, since the code doesn't do any regex matching at all (just zsh-like wildcard matching - other copies of this code living in the Mozilla tree use better names like "NS_WildCardMatch()"). If the code is left in lib/util, then at least the names should be changed - exporting PORT_RegExpCaseSearch as a public function from libnssutil3 seems like a bad idea to me.

In a further step, cert_TestHostName() could be actually modified to not rely on PORT_RegExpCaseSearch() any longer, in my opinion (or is there any need for supporting shell-style matching besides the '*' character?). Provided that there is a consensus in the NSS team on what exactly should be implemented, I would be willing to give it a try.

What are the chances of getting this into 3.12 (and Fx 3, therefore)? Whom can/should I ask for review?
Comment 17 Kaspar Brand 2007-11-10 07:39:15 PST
Created attachment 288138 [details] [diff] [review]
Test program (for illustration purposes only)

Test program producing the following results, *after* the patch from attachment 288137 [details] [diff] [review] is applied (arbitrary patterns/hostnames to test can be specified as cmdline arguments):

---------- snip ----------
*.example.com does not match hostname www
*.example.com does not match hostname example.com
*.example.com MATCHES hostname www.example.com
*.example.com MATCHES hostname foo.example.com
*.example.com MATCHES hostname foobar.example.com
*.example.com does not match hostname foo.bar.example.com

www*.example.com does not match hostname www
www*.example.com does not match hostname example.com
www*.example.com MATCHES hostname www.example.com
www*.example.com does not match hostname foo.example.com
www*.example.com does not match hostname foobar.example.com
www*.example.com does not match hostname foo.bar.example.com

f*.example.com does not match hostname www
f*.example.com does not match hostname example.com
f*.example.com does not match hostname www.example.com
f*.example.com MATCHES hostname foo.example.com
f*.example.com MATCHES hostname foobar.example.com
f*.example.com does not match hostname foo.bar.example.com

foo*bar.example.com does not match hostname www
foo*bar.example.com does not match hostname example.com
foo*bar.example.com does not match hostname www.example.com
foo*bar.example.com does not match hostname foo.example.com
foo*bar.example.com MATCHES hostname foobar.example.com
foo*bar.example.com does not match hostname foo.bar.example.com

* MATCHES hostname www
* does not match hostname example.com
* does not match hostname www.example.com
* does not match hostname foo.example.com
* does not match hostname foobar.example.com
* does not match hostname foo.bar.example.com

foo.*.example.com does not match hostname www
foo.*.example.com does not match hostname example.com
foo.*.example.com does not match hostname www.example.com
foo.*.example.com does not match hostname foo.example.com
foo.*.example.com does not match hostname foobar.example.com
foo.*.example.com does not match hostname foo.bar.example.com

*.*.example.com does not match hostname www
*.*.example.com does not match hostname example.com
*.*.example.com does not match hostname www.example.com
*.*.example.com does not match hostname foo.example.com
*.*.example.com does not match hostname foobar.example.com
*.*.example.com does not match hostname foo.bar.example.com
---------- snip ----------
Comment 18 Wan-Teh Chang 2007-11-10 11:59:01 PST
Comment on attachment 288137 [details] [diff] [review]
Minimal patch (addresses item b in comment 6)

>+                    /* remaining string must not contain any dots */
>+                    if (str[x] && PORT_Strchr(&str[x], '.'))
>+                        return NOMATCH;
>+                    else
>+                        return MATCH;


Should we allow a single terminating dot?  I seem
to recall DNS names can be terminated with a dot.

    /*
     * renaming string must not contain any dot
     * followed by another component
     */
    if (str[x]) {
        char *dot = PORT_Strchr(&str[x], '.');
        if (dot and dot[1])
            return NOMATH;
    }
    return MATCH;
Comment 19 Reed Loden [:reed] (use needinfo?) 2007-11-10 12:04:44 PST
It wouldn't upset me at all if we just dropped backwards compatibility and only supported RFC 2818 like some other browsers do. ;)

In particular, I see sites misusing wildcard certs such as *.example.tld for all subdomains under example.tld (foo.bar.example.tld, etc.), which is a violation of RFC 2818, but this violation is currently allowed in Firefox (due to current NSS). :(
Comment 20 mozbug1 2007-11-11 10:40:31 PST
(In reply to comment #17)
> Created an attachment (id=288138) [details]
> Test program (for illustration purposes only)
<snip>
> *.*.example.com does not match hostname foo.bar.example.com

 *.*.example.com does *should* match foo.bar.example.com.  My company uses a *.* certificate and this would break our website in firefox.
Comment 21 Kaspar Brand 2007-11-11 22:03:39 PST
(In reply to comment #18)
> Should we allow a single terminating dot?

I don't recommend doing so (or if we really do, then we should just strip off a trailing dot at the beginning of cert_TestHostName, and not modify _shexp_match further).

> I seem to recall DNS names can be terminated with a dot.

They're not permitted RFC-wise, actually... RFC 952 says:

   1. A "name" (Net, Host, Gateway, or Domain name) is a text string up
   to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus
   sign (-), and period (.).  Note that periods are only allowed when
   they serve to delimit components of "domain style names". (See
   RFC-921, "Domain Name System Implementation Schedule", for
   background).  No blank or space characters are permitted as part of a
   name. No distinction is made between upper and lower case.  The first
   character must be an alpha character.  The last character must not be
   a minus sign or period.

[Note that RFC 1123 slightly changes one of these requirements:

      The syntax of a legal Internet host name was specified in RFC-952
      [DNS:4].  One aspect of host name syntax is hereby changed: the
      restriction on the first character is relaxed to allow either a
      letter or a digit.  Host software MUST support this more liberal
      syntax.

 I'm not aware of any other updates to RFC 952 which would change this syntax.]

The "trailing dot issue" is actually the topic of bug 134402, and normalizing the hostname in PSM (maybe even in Necko?) seems like the better fix to me. (If really considered appropriate/necessary - IE7 e.g. also treats www.example.com and www.example.com. as different names, as does Opera.)
Comment 22 Kaspar Brand 2007-11-14 07:53:15 PST
Created attachment 288681 [details] [diff] [review]
Alternative patch for (more restrictive) wildcard matching

(In reply to [my own] comment #16)
> In a further step, cert_TestHostName() could be actually modified to not rely
> on PORT_RegExpCaseSearch() any longer, in my opinion (or is there any need for
> supporting shell-style matching besides the '*' character?).

Here's an alternative patch (for cert_TestHostName) which implements a more "radical" solution, by further limiting the cases where '*' is interpreted as a wildcard character. From the explanation in the source:

   /* for a cn pattern to be considered valid, the wildcard character...
      - may occur in the first component only, and must be its last character
      - may occur only once
      - may be preceded by additional characters
    */

Of course this is (still) in line with RFCs 2595, 2818 and 4513, and has the advantage of no longer depending on PORT_RegExpCaseSearch (so portreg.{h,c} could actually be dropped from NSS, since cert_TestHostName is its only caller).

Can somebody (Nelson?) advise on how I should proceed? Is this patch acceptable for review, or would it also need to cover the changes to lib/util? Thanks for any guidance.
Comment 23 Kaspar Brand 2007-11-14 08:00:52 PST
As a small addendum: I'm aware of the current priority of this bug (P3), but given the fact that Firefox 3 will introduce considerable improvements when dealing with invalid certificates (bug 327181), wouldn't this be a good opportunity to tighten wildcard matching at the same time (making it RFC compliant)? Could we increase its priority therefore?
Comment 24 mozbug1 2007-11-14 08:45:36 PST
While reading RFC 2595:

- A "*" wildcard character MAY be used as the left-most name
     component in the certificate.  For example, *.example.com would
     match a.example.com, foo.example.com, etc. but would not match
     example.com.

And in RFC 2818:

 Names may contain the wildcard
   character * which is considered to match any single domain name
   component or component fragment.

So *.*.example.com should work according to 2818 but not 2595. But 2818 is "HTTP Over TLS" and 2595 is "Using TLS with IMAP, POP3 and ACAP", and since Firefox is a web browser and not an email client I think it should follow 2818.  Furthermore the wording in 2595 seems to have been intended to ensure that wildcards were leftmost, and to disallow cases example.*.  It seems to me just sloppy wording on the part of the author that disallowed *.*.example.com

(In reply to comment #20)
> (In reply to comment #17)
> > Created an attachment (id=288138) [details] [details]
> > Test program (for illustration purposes only)
> <snip>
> > *.*.example.com does not match hostname foo.bar.example.com
> 
>  *.*.example.com does *should* match foo.bar.example.com.  My company uses a
> *.* certificate and this would break our website in firefox.
> 

Comment 25 Nelson Bolyard (seldom reads bugmail) 2007-11-14 18:31:41 PST
I concur with Kaspar's comment 21.

Here is some perspective that will guide decisions on which way to go.

1) NSS is used by many applications, not just FireFox, and not even just 
Mozilla client products.  So it must meet the needs of a general audience.

2) libSSL does not decide for itself whether a cert is valid to be used as
a server cert.  Instead, it calls a callback function that is supplied by 
the application (!).  That callback function decides.  The point here is 
that the responsibility for deciding if a cert passes or fails rests upon
the application.  The application provides the function that makes the 
decision according to the application's criteria.  If Mail and Web 
applications have different criteria, they should provide different 
callback functions.

3) NSS provides a function that an application can choose to use as that 
callback function, IFF it meets that appliation's needs for this purpose.  
It is SSL_AuthCertificate.  It calls CERT_VerifyCertNow to verify that the
cert chain is valid, and it calls CERT_VerifyCertName to determine that 
the cert is valid for the host name that the application has given to NSS.
It was written before either RFC 2818 or RFC 2595 were written.  
It is not intended to work only with https or only with mail protocols, 
but to be more generally useful.  Its acceptance grammar is intended to 
be the union of those of the various protocols for which it will be used.
It should declare that a cert is valid for a host name if any of the 
protocols for which it may be used would declare it to be valid.

It appears to me that the rules for RFC 2818 allow a proper superset of 
wildcard patterns that are allowed by RFC 2595.

Having said that, it does seem that wildcard patterns with stars in the 
top two levels of domain (such as "*" and "*.com") are undesirable.  So, 
I would be willing to impose a new restriction, that wildcards must be 
followed by at least two dots (that is, two domains) excluding a trailing 
dot, which I do not propose to ignore (in concurrence with comment 21).
Comment 26 Kaspar Brand 2007-11-15 11:21:03 PST
(In reply to comment #25)
> Having said that, it does seem that wildcard patterns with stars in the 
> top two levels of domain (such as "*" and "*.com") are undesirable.

When modifying the "*" to no longer match a ".", CN=* could still make some sense for Intranet URLs (such as "https://webmail"). I'm not opposed to this drop this option as well, but others might complain vociferously if we do so.

> I would be willing to impose a new restriction, that wildcards must be 
> followed by at least two dots (that is, two domains) excluding a trailing 
> dot, which I do not propose to ignore (in concurrence with comment 21).

Would you want to support patterns like www.*.example.com? It's true that RFC 2818 doesn't disallow such patterns (since it doesn't require the wildcard character to occur in the left-most component only), but given a number of other recent TLS related RFCs and Internet drafts, my impression is that the current consensus is to allow the in the first component only:

- RFC 4642 (October 2006), TLS with NNTP
- RFC 4954 (July 2007), STARTTLS SMTP extension
- draft-ietf-nsis-ntlp-14 (July 2007), General Internet Signalling Transport
- draft-badra-tls-netconf-04 (Oct. 2007), NETCONF over TLS

All these basically use the wording from RFC 2595 ("MAY be used as the left-most name component in the certificate"), so if RFC 2818 - from May 2000 - would be written today, my guess is that we'd see the same wording there, too.

Only allowing the "*" in the first component is also in line with the behavior implemented by Microsoft's Schannel library since Windows 2000 SP1 (see http://support.microsoft.com/kb/258858 - note that some of the "accepted wildcard examples" are completely wrong; the text description is accurate, however).

Therefore I still suggest going for the solution outlined in comment 22 (possibly with dropping support for "dotless" names). It's both in line with the RFCs and with the behavior of a very widespread implementation of another vendor, so chances are pretty small that this will "break the Net"...

What solution does the NSS team favor? Thanks for additional comments/opinions.
Comment 27 Nelson Bolyard (seldom reads bugmail) 2007-11-15 14:55:20 PST
As far as I am concerned, host names in certs must always be FQDNs.  
I don't know of ANY CA that will issue certs with non-FQDN host names,
e.g. for "webmail".  If no CA issues them, then any certs with such names
in them must be ones that require the user to explicitly trust them.
I have no problem with saying that users must use FF3's new ability to 
permanently remember error overrides for certs with mismatched host names 
if they want to associate certs with non-FQDN host names.
Comment 28 Wan-Teh Chang 2007-11-15 15:21:42 PST
Bug 401317 has a cert for "www".  Bug 401317 comment 3 named the
CAs that will issue certs with non-FQDN host names.
Comment 29 Nelson Bolyard (seldom reads bugmail) 2007-11-15 16:01:38 PST
I concur with the reporter of bug 401317 that certs with simple host names
should not validate.   What does IE do with them?
Comment 30 Kaspar Brand 2007-11-15 22:21:01 PST
(In reply to comment #29)
> I concur with the reporter of bug 401317 that certs with simple host names
> should not validate.   What does IE do with them?

They work under IE (that's probably why CAs are issuing them in the first place). CN=* doesn't work at all with IE, which would be an argument for dropping support for this in NSS as well. So we would have:

   /* for a cn pattern to be considered valid, the wildcard character...
      - may occur in an FQDN only
      - may occur in the first component only, and must be its last character
      - may occur only once
      - may be preceded by additional characters
    */

Does that sound like a reasonable solution to our problem?

(Re:
> I would be willing to impose a new restriction, that wildcards must be 
> followed by at least two dots (that is, two domains) excluding a trailing 
> dot, which I do not propose to ignore

That's basically a good idea, but it has the drawback that it isn't really a "universal" solution - there is a considerable number of TLDs where more that two dots would be required to make this restriction effective [see http://lxr.mozilla.org/mozilla/source/netwerk/dns/src/effective_tld_names.dat and bug 331510 [the nsEffectiveTLDService] for what Necko is doing about this - maybe PSM could make use of it?.)
Comment 31 Nelson Bolyard (seldom reads bugmail) 2007-11-16 11:10:27 PST
Perhaps PSM could make use of Necko's TLD stuff, but NSS cannot, so I am 
looking for what we can do in NSS.
Comment 32 Kaspar Brand 2007-11-19 10:16:54 PST
Created attachment 289348 [details] [diff] [review]
Alternative patch for wildcard matching, incorporating suggestion from comment 25

(In reply to comment #31)
> Perhaps PSM could make use of Necko's TLD stuff, but NSS cannot, so I am 
> looking for what we can do in NSS.

A thorough solution probably needs something similar to the database from nsEffectiveTLDService, but I assume that this is not what you want to have in NSS. Thus, incorporating your previous suggestion

> impose a new restriction, that wildcards must be followed by at least two dots
> (that is, two domains) excluding a trailing dot

is probably better than nothing, and therefore I'm proposing this updated patch and am asking for review. (If that solution gets accepted, I could then prepare another patch which removes the PORT_RegExp stuff from NSS - unless there's really a good reason to keep that code in the library.)
Comment 33 Nelson Bolyard (seldom reads bugmail) 2007-11-30 18:48:20 PST
Comment on attachment 289348 [details] [diff] [review]
Alternative patch for wildcard matching, incorporating suggestion from comment 25

After reading this patch, it appears to me that it behaves as follows:

> static SECStatus
> cert_TestHostName(char * cn, const char * hn)
> {
	    
>+    char *wildcard = PORT_Strchr(cn, '*');
>+    char *firstdot = PORT_Strchr(cn, '.');
>+    char *seconddot = firstdot ? PORT_Strchr(firstdot+1, '.') : NULL;
>+
>+   /* for a cn pattern to be considered valid, the wildcard character...
>+      - may only occur in an FQDN with at least 3 components
>+      - may occur in the first component only, and must be its last character
>+      - may occur only once
>+      - may be preceded by additional characters
>+    */
>+    if (wildcard && firstdot && seconddot && *(seconddot+1)
>+        && firstdot == wildcard + 1
>+        && seconddot - firstdot > 1
>+        && PORT_Strrchr(cn, '*') == wildcard
>+        && PORT_Strncasecmp(cn, hn, wildcard - cn) == 0
>+        && PORT_Strcasecmp(firstdot, PORT_Strchr(hn, '.')) == 0)
>+        /* valid wildcard pattern match */

It implements these rules for the pattern in "cn":
- One and only one asterisk.
- No dots to the left of the asterisk, but other characters are allowed
to precede the asterisk.
- The asterisk must be followed immediately by the first dot.
- At least two dots, and second dot must not be last character in string.
(Note that this does not eliminate the possibility of a trailing dot.)
- At least one character between first dot and second dot.

If cn contains characters other than dot before the asterisk, then it
will compare those characters against an equal number of leading 
characters from hn, and any non-match will mean a pattern match failure.
Otherwise, it will compare the strings beginning with the first dot in 
each of cn and hn.

This patch relies on the fact that, presently, PORT_Strcasecmp is 
defined as PL_strcasecmp, and unlike POSIX strcasecmp, PL_strcasecmp 
is defined to NOT crash if either input string arguement is NULL.

Since the PORT_ functions exist to allow implementors to choose 
different implemenations for their platforms, and PORT_Strcasecmp
could be defined as some other implementation, I suggest that the
patch should call PL_strcasecmp directly, to ensure that it gets 
an implementation that has the desired property. 

I'd prefer if PORT_Strchr(hn, '.') was called separately, and its
result stored in a pointer, and used only if it is non-NULL.  

>+        return SECSuccess;
>+    else if (PORT_Strcasecmp(hn, cn) == 0)
>+        /* no valid wildcard pattern, but literal match */
>+        return SECSuccess;
>+    else {

Eliminate the elses immediately after returns.  They serve no purpose.

>+        PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
>+        return SECFailure;
>+    }
> }

Unindent the final block and remove the braces from it.

Did you mean to disallow trailing dots from the patterns?
The present rules allow
  *.a.b.
but do not allow
  *.a.
Is that intentional?

Assuming it is, then I suspect this patch does what Kaspar intended for it 
to do.  So the remaining question is: are any of NSS's customers (teams that
develop products that use NSS) going to have a fit over this change?
I will ask about this in various newsgroups and mailing lists.  

In the mean time, Kaspar, please address those review comments.
Oh, and put an asterisk in every line in the block comment, so they 
form a column.
Comment 34 Kaspar Brand 2007-11-30 23:31:27 PST
Created attachment 290963 [details] [diff] [review]
Alternative patch for wildcard matching v3, addressing review comments

(In reply to comment #33)

Thanks for the review, Nelson.

> I suggest that the
> patch should call PL_strcasecmp directly, to ensure that it gets 
> an implementation that has the desired property. 
> 
> I'd prefer if PORT_Strchr(hn, '.') was called separately, and its
> result stored in a pointer, and used only if it is non-NULL.

I did the latter, so it's not necessary to switch to PL_strcasecmp, I think. I also changed the name of two variables (since I'm introducing "firsthndot"), but other than that, there are no changes to the code logic.

> Eliminate the elses immediately after returns.  They serve no purpose.

Done.

> Unindent the final block and remove the braces from it.

Done.

> Did you mean to disallow trailing dots from the patterns?
> The present rules allow
>   *.a.b.
> but do not allow
>   *.a.
> Is that intentional?

Yes. It follows from implementing your suggestion in comment 25:

> a new restriction, that wildcards must be followed by at least
> two dots (that is, two domains) excluding a trailing dot

["*.a." is only followed by one dot, not counting the trailing one.]

> Oh, and put an asterisk in every line in the block comment, so they 
> form a column.

Done.
Comment 35 Kaspar Brand 2007-11-30 23:35:48 PST
Created attachment 290964 [details] [diff] [review]
Updated test program (for illustration purposes only), incorporating code from patch v3 [cf. comment 34]

The difference to the output shown in comment 17 is that it will no longer allow the "foo*bar.example.com" and "*" patterns (i.e. the last two lines with "MATCHES" now turn into a "does not match").
Comment 36 Nelson Bolyard (seldom reads bugmail) 2007-12-01 03:52:28 PST
When I asked 
> Did you mean to disallow trailing dots from the patterns?
my point was that the patch I was reviewing does NOT disallow trailing dots.
It merely doesn't count them in the count of dots following the star.
So *.a.b. is allowed, despite the trailing dot.
I asked that question because of bug 134402.
Kaspar, you may be interested in that bug.
Comment 37 Kaspar Brand 2007-12-01 04:18:12 PST
(In reply to comment #36)
> When I asked 
> > Did you mean to disallow trailing dots from the patterns?
> my point was that the patch I was reviewing does NOT disallow trailing dots.
> It merely doesn't count them in the count of dots following the star.
> So *.a.b. is allowed, despite the trailing dot.

Correct, but the primary purpose of the patch is to change/fix the wildcard matching, not checking whether "cn" contains a valid host name / host name pattern. If someone really has a cert with "CN=*.example.com.", then it doesn't hurt if that cert is working for "https://www.example.com./", I'd say.

(Checking for "proper" cn patterns is outside the scope of the cert_TestHostName function, IMO. If we would really want to disallow trailing dots, then we would have to ban things like "-*.example.com" for cn as well. And a number of others, probably...)

> I asked that question because of bug 134402.
> Kaspar, you may be interested in that bug.

I'm aware of that one, yes (see comment 21 above ;-).
Comment 38 Nelson Bolyard (seldom reads bugmail) 2007-12-04 19:01:16 PST
Comment on attachment 290963 [details] [diff] [review]
Alternative patch for wildcard matching v3, addressing review comments

I believe this patch does what you want it to do.
The question is: do we really want to make this change?
I'm trying to find that out now, by making inquiries in several channels.
Comment 39 Nelson Bolyard (seldom reads bugmail) 2007-12-06 15:56:46 PST
(In reply to comment #30)
Kaspar, In comment 30.  You wrote;

> CN=* doesn't work at all with IE,

Some followup questions to that:

Do you mean that a cert with CN=* will not match against a "simple host 
name" URL such as https://myhost/ in IE? 
Or do you mean only that it will not match any names containing dots?
Or do you mean that "*" is allowed only in Subject Alt Names, not in CN ?

Do you know what test/rule makes it fail?
Does IE require that at least one dot follow an askerisk?
Does *.com work with IE?

There have been many objections registered in various bugs to the fact that 
NSS allows CN=* to match any DNS name including FQDNs, but the issues in 
those complaints seem to be resolved by disallowing * to match any dots.  
There seems to be a desire to allow "*" to match simple host names (names
with no dots), and I do not see that any of the above-cited RFCs disallows it.
OTOH, if it doesn't work with IE, then there is a pretty good case for 
not supporting it.
Comment 40 Kaspar Brand 2007-12-07 02:27:17 PST
(In reply to comment #39)
> Kaspar, In comment 30.  You wrote;
> 
> > CN=* doesn't work at all with IE,
> 
> Some followup questions to that:
> 
> Do you mean that a cert with CN=* will not match against a "simple host 
> name" URL such as https://myhost/ in IE? 
> Or do you mean only that it will not match any names containing dots?
> Or do you mean that "*" is allowed only in Subject Alt Names, not in CN ?

"*" doesn't match any unqualified ("dotless") name in IE, no matter if there's a CN=* or a dNSName entry with "*" in the subjectAltName extension. (And IE doesn't allow "*" to match for any host name which includes a dot either, of course - that's what I meant when saying "doesn't work at all".)

> Do you know what test/rule makes it fail?

I can't say what specific rule(s) IE uses, as I haven't seen its sources :-) But from all my tests I conclude that IE's rules are pretty similar to the ones which are now proposed by the latest patch (attachment 290963 [details] [diff] [review]).

> Does IE require that at least one dot follow an askerisk?

Yes - and more than a dot must follow, actually: "CN=*." (or a subjectAltName entry with this pattern, for that matter) doesn't work for "https://myhost./", e.g.

> Does *.com work with IE?

No.

> There seems to be a desire to allow "*" to match simple host names (names
> with no dots), and I do not see that any of the above-cited RFCs disallows it.
> OTOH, if it doesn't work with IE, then there is a pretty good case for 
> not supporting it.

Yes, this was also the conclusion I came to in comment 30, based on which I implemented v2 of the patch (attachment 289348 [details] [diff] [review], which is now obsoleted by v3).
Comment 41 Kaspar Brand 2007-12-20 09:13:21 PST
(In reply to comment #38)
> (From update of attachment 290963 [details] [diff] [review])
> I believe this patch does what you want it to do.
> The question is: do we really want to make this change?
> I'm trying to find that out now, by making inquiries in several channels.

Nelson, do you have news on the outcome of these inquiries? Were there objections/arguments which would require a reconsideration of the solution implemented by patch v3?

If not, can we go one step further? (I guess the patch needs a second review - who would be the right person to ask?)
Comment 42 Reed Loden [:reed] (use needinfo?) 2008-01-07 21:44:58 PST
Hey guys... time is running out to get this in. Nelson, can you review the patch? Does anybody else need to look at it? I'd like to get some momentum going again on this bug. Thanks! :)
Comment 43 Nelson Bolyard (seldom reads bugmail) 2008-01-08 17:51:42 PST
OK, here's the issue.  This change will definitely cause some number of businesses to suddenly find that certificates that have been working for 
them for a long time are no longer being accepted as valid.  It would
effectively be a break in binary compatbility for NSS.  

NSS cannot break binary compatbility UNLESS such a break MUST be done to 
correct a vulnerability that is widely perceived to be a serious one.  
This issue is not presently widely perceived to be a serious vulnerability.

So, our choices are:
a) Have the new behavior and the old behavior coexist in NSS, preserving the 
present behavior with the existing function, or 
b) wait for public consciousness of this vulnerability to be raised.

The simplest thing to do, and the one I would advocate, is to introduce 
the new functionality as a new function, rather than as a modification of 
an old function.  Then applications can control whether they get the old
or new behavior, and applications that make no change continue to experience
compatible behavior.
Comment 44 Nelson Bolyard (seldom reads bugmail) 2008-01-16 21:13:22 PST
Comment on attachment 290963 [details] [diff] [review]
Alternative patch for wildcard matching v3, addressing review comments

SAdly, I must give this patch r-.  
See the preceding comment for the reasons.
Comment 45 Nelson Bolyard (seldom reads bugmail) 2008-01-26 13:52:02 PST
I found a live webmail server on the internet that relies on this "feature".
https://mail.netidentity.com.cust.hostedemail.com/ 
Their cert uses this wildcard pattern:  *.hostedemail.com
They're counting on '*' to match "mail.netidentity.com.cust".
Comment 46 Reed Loden [:reed] (use needinfo?) 2008-01-26 13:58:41 PST
(In reply to comment #45)
> I found a live webmail server on the internet that relies on this "feature".
> https://mail.netidentity.com.cust.hostedemail.com/ 
> Their cert uses this wildcard pattern:  *.hostedemail.com
> They're counting on '*' to match "mail.netidentity.com.cust".

There is _always_ going to be somebody not doing what they are supposed to be doing. That doesn't mean we shouldn't fix it to be correct, with regards to RFC 2818. Please note that Safari 3.x and IE 7 both consider abusing SSL certificates like that as a failure. Safari completely refuses to load the site while IE 7 allows the user to continue on after accepting a warning dialog. I just don't see why one site (or even multiple sites) doing something wrong should cause us not to fix an actual bug that could be abused by people for nefarious purposes.
Comment 47 Vincent Régnard 2008-06-06 07:06:37 PDT
This is really problematic since zone delagation possibility extend the validity of the certificate to untrusted fqdn or organisations and this has obvious security issues !

This is easy to understand: *.domain.com in the cn stands for any domain name under  .domain.com. * matches everything but the dot ! This is how trusted CAs treat it according to RFC 2818. 

With perl the regex to achieve this is as simple as: 

/^[^\.]+\.domain\.com$/

this should normally not take years to implement ? Can you please give a final decision on that ?

IE 6 and 7 now implement it that way !!
Comment 48 Jo Hermans 2008-06-10 08:43:34 PDT
*** Bug 438322 has been marked as a duplicate of this bug. ***
Comment 49 Kaj J. Niemi 2008-06-11 00:50:50 PDT
It would be nice if someone could make this bug happen considering the two other major browsers (IE, Safari) behave according to RFC 2818. Nobody building a public service/site can use this feature as they need to have it work with all three without security warnings or errors. FF is not at 99% market share yet.
Comment 50 Nelson Bolyard (seldom reads bugmail) 2009-03-06 18:04:38 PST
Comment on attachment 290963 [details] [diff] [review]
Alternative patch for wildcard matching v3, addressing review comments

The time for this change is rapidly approaching.  Stay tuned.
Comment 51 Nelson Bolyard (seldom reads bugmail) 2009-03-10 16:29:45 PDT
Created attachment 366705 [details] [diff] [review]
alternative patch v4 - preserve old code with environment variable

This patch is Kaspar's v3 patch, modified to allow old code to be 
preserved with an environment variable.  Kaspar, if you approve, 
I'll commit this and give you credit. (is that a conflict of interest?)
Comment 52 Kaspar Brand 2009-03-11 07:55:44 PDT
(In reply to comment #51)
> This patch is Kaspar's v3 patch, modified to allow old code to be 
> preserved with an environment variable.  Kaspar, if you approve, 
> I'll commit this and give you credit. (is that a conflict of interest?)

I don't like the option of adding this sort of "backdoor", but if it's the only way to make this change happen, then you have my approval.

Looking at patch v4, both the variable names and the comments now insinuate that the current code supports regex matching:

+    if (useRegex < 0) {
+        useRegex = (NULL != PR_GetEnv("NSS_USE_REGEX_WILDCARDS"));
+    }
+    if (useRegex) {
+    	/* Backward compatible code, uses full Regular Expressions. */
+	int regvalid = PORT_RegExpValid(cn);
+	if (regvalid != NON_SXP) {
+	    SECStatus rv;
+	    /* cn is a regular expression, try to match the shexp */
+	    int match = PORT_RegExpCaseSearch(hn, cn);

This is not the case, however, as I wrote in comment 16. Perhaps the environment variable should be named NSS_USE_SHEXP_WILDCARDS, and the comment should make it clear that it's shell-style matching, not regular expressions.

And since you're mentioning RFC 2818 further down in the code (which is certainly useful), maybe it would make sense to add references to RFCs 2595, 4513, 4642, and 4954 as well - these are actually on the standards track, in contrast to RFC 2818.
Comment 53 Nelson Bolyard (seldom reads bugmail) 2009-03-11 13:07:52 PDT
Created attachment 366877 [details] [diff] [review]
patch v5 - don't call it regex

I used Kaspar's suggestion for the environment variable name.

Each of the RFCs cited in the preceding comment defines a somewhat 
different standard from the one implemented in this patch, so I prefer
to continue to cite only the RFC that we're trying to match.
This routine isn't meant to be the one-size-fits-all cert name matcher.
It's really for https.  If other application protocol implementations 
(such as email) choose to use it, that's their decision, but they're 
able to supply alternate functions for this purpose.
Comment 54 Wan-Teh Chang 2009-03-11 20:57:17 PDT
Comment on attachment 366877 [details] [diff] [review]
patch v5 - don't call it regex

r=wtc.

>-** may modify cn, so caller must pass a modifiable copy.
>+** This function may modify *cn, so caller must pass a modifiable copy.

Let's still call it cn instead of *cn.  You're still using cn
in the other comments in this function.

Nit: The name of the environment variable should ideally
include CERT_NAME.  Also note that the old code allows not
only shell-style wildcards but also unions (|), so WILDCARDS
doesn't completely describe what the old code allows.

>+    if (useShellExp) {
>+    	/* Backward compatible code, uses full Regular Expressions. */

The comment says "regular expressions", but the environment
variable and static variable say "shell expressions".  They
seem to contradict either other.

>+	if (wildcard && secondcndot && secondcndot[1] && firsthndot

Should we also require that secondcndot[1] != '.'?

>+	    && PORT_Strrchr(cn, '*') == wildcard

Is it cheaper to test
            && PORT_Strchr(cn+1, '*') == NULL
instead?
  
>+	    && !PORT_Strncasecmp(cn, hn, wildcard - cn)

I verified that if wildcard - cn is 0, PORT_Strncasecmp
returns the desired 0.  The reason I checked this is that
for the similar function strncmp, the return value when the
third argument is 0 doesn't seem to be specified:
http://www.opengroup.org/onlinepubs/000095399/functions/strncmp.html           

>+    /* CN has no wildcard or shell expression. 

Nit: use lowercase cn to match the parameter name.
Comment 55 Wan-Teh Chang 2009-03-11 21:07:36 PDT
Bug 261900 is a reminder that the old NSS code allows
unions (|) in certificate names.
Comment 56 Nelson Bolyard (seldom reads bugmail) 2009-03-12 00:22:14 PDT
Comment on attachment 366877 [details] [diff] [review]
patch v5 - don't call it regex

I made the changes to comments and variable names suggested by wtc.
Checking in certdb.c; new revision: 1.97; previous revision: 1.96
Comment 57 Nelson Bolyard (seldom reads bugmail) 2009-03-13 15:22:21 PDT
I received some feedback from a Sun Java developer, saying that JSSE's 
interpretation of wildcards allows "*" to appear any number of times in 
each component of a DNS name in a cert.  It simply does not match a dot.

So, for example, given an attempt to connect to https://java.sun.com  
JSSE would match java.sun.com with 
  j*.sun.com 
 *va.sun.com 
j*va.sun.com 
j*v*.sun.com 
  java.*.com 
    java.*.* 
       *.*.* 
but would not match 
      java.* 
    *sun.com

The writer believes that behavior is what is required by RFC 2818.
Comment 58 georgi - hopefully not receiving bugspam 2009-03-13 22:59:35 PDT
  java.*.com
    java.*.*
       *.*.*

the interesting part which cert seller will sell such certs, especially "*.*.*"

from which cert seller should i buy?
Comment 59 Kaspar Brand 2009-03-13 23:38:55 PDT
(In reply to comment #57)
> The writer believes that behavior is what is required by RFC 2818.

RFC 2818 allows the wildcard character to appear in components other than the leftmost one, that's correct. The goal of my patch, however, was to also comply with RFCs 2595 and 4513 at the same time. See comment 22 and comment 26.

(In reply to comment #58)
> the interesting part which cert seller will sell such certs, especially "*.*.*"
> 
> from which cert seller should i buy?

You'll have a (very?) hard time finding one, I guess. And they will definitely not work with that other major browser.
Comment 60 georgi - hopefully not receiving bugspam 2009-03-14 00:31:44 PDT
>You'll have a (very?) hard time finding one, I guess. 

sure. i tried the "*~.whatever" trick with some sellers and they sanitized it.
though i tried it with ordinary cert, not wildcard cert - wildcard certs were too expensive for the odds of the experiment imo.

>And they will definitely not work with that other major browser.

the firefox userbase is ok for me ;)
Comment 61 Wan-Teh Chang 2009-03-14 09:13:45 PDT
Kaspar, why do you disallow a wildcard to be followed by
additional characters in the leftmost component?  That
requirement is not in RFCs 2595 and 4513.

We should update the comment (citing RFCs 2595 and 4513)
to match the code.  The current comment "New approach
conforms to RFC 2818" is not accurate.
Comment 62 Kaspar Brand 2009-03-16 09:28:51 PDT
(In reply to comment #61)
> Kaspar, why do you disallow a wildcard to be followed by
> additional characters in the leftmost component?  That
> requirement is not in RFCs 2595 and 4513.

It is, actually: both allow it as "*the* left-most component/DNS label", which implies that it can neither be preceded nor followed by any additional characters.

The rules which I implemented don't follow slavishly the RFCs in any case - e.g., none of them requires the component with the wildcard character to be followed by two additional components. We arrived at this solution in earlier discussions (see comment 25, inter alia).
Comment 63 Johnathan Nightingale [:johnath] 2009-04-16 12:02:51 PDT
This bug is marked blocking1.9.1. As I understand it, this change was included in the NSS_3_12_3_RC0 tag, which Kai pushed to the 1.9.1 branch in bug 481968 (changeset http://hg.mozilla.org/releases/mozilla-1.9.1/rev/f160224c5221 ).  Therefore, I'm marking this bug fixed1.9.1.

Please let me know if I've misunderstood.
Comment 64 Kevin Brosnan 2009-05-28 21:32:41 PDT
*** Bug 495339 has been marked as a duplicate of this bug. ***
Comment 65 Kevin Brosnan 2009-05-28 22:11:25 PDT
This is not fixed on Mozilla 1.9.1 or Mozilla-central http://mxr.mozilla.org/mozilla-central/source/security/nss/lib/certdb/certdb.c#1446
Comment 66 Wan-Teh Chang 2009-05-28 22:31:40 PDT
It's the opposite.  Because this bug is fixed, the cert in
bug 495339 no longer matches that host name.
Comment 67 Brendan Hide 2009-05-29 23:32:01 PDT
From my reading of the above, we're now following RFC's blindly with little regard for context. I posted bug 495339. Unfortunately, RFCs aren't infallible.

1. Bad CAs issuing * certs without proper verification? rm -f
2. Prove that removing backwards compatibility has tangibly improved security. Change this bug to REOPENED.
3a. Are regex's supported?
 b. If so, do any CAs support regex's or is this only for self-signed certs?
4. Don't "fix" the trailing dot - it ain't broke

1. Respectable commercial Cert providers shouldn't be issuing certificates for "*.com" or "*.co.za" or "*" or any other similar address. If there's a vendor that does issue these certificates they should be considered untrustworthy and removed from the CA repository.

The cert vendors I've worked with verify that the certificate is actually being issued to the domain administrator. The same applies here - if the CA isn't verifying that the certificate is being issued to the domain's owners then the CA must be removed from the CA repository.

Based on the above, I'd like to see how anyone might prove to a CA that they own the .com domain. If you're able to do it, remove that CA from the repository.

2. The example in my bug 495339 has an address under glodns.net. glodns.net has a certificate that has been issued to the administrators in charge of glodns.net. The administrators of glodns.net are asserting that the full address in question does in fact belong to the glodns.net network - only now we're interpreting things differently from before and the expected behaviour is broken.

Most certificate vendors describe their wildcard certificates as "unlimited subdomains". foo.bar.example.com is still a subdomain of example.com no matter how many dots inbetween the foo and example.

What is the purpose of removing the backwards compatibility here? Can you give me a plausible risk that having the wildcard NOT match the dot really mitigates? "Its RFC" isn't a good answer here. As I said above, RFCs aren't infallible and we've been ignoring it for a VERY long time without any complaints.

Please change this bug to REOPENED.

3a. Are regular expressions supported in any way as mentioned in comment 0? I'm not at work and I don't have the resources at hand to test this properly. I can test this Monday on a self-signed cert.

3b. Assuming regex's are supported, do any cert vendors support regex's?

4. Finally, it seems nobody wants to "fix" the trailing dot but it might come up again - it is the Internet root. In DNS, the . is always implied. Ignoring the trailing dot is fine. Here are my DNS dig results for "bugzilla.mozilla.org" and "bugzilla.mozilla.org.". Take note of the trailing dots in the results for both queries:

> [ brendan@swift : 08:07:17 : ~ ]
> :) dig bugzilla.mozilla.org | grep . | grep -v "^;"
> bugzilla.mozilla.org.   60      IN      CNAME   bugzilla-mozilla-org.geo.mozilla.com.
> bugzilla-mozilla-org.geo.mozilla.com. 1661 IN CNAME dyna-bugzilla.nslb.sj.mozilla.com.
> dyna-bugzilla.nslb.sj.mozilla.com. 600 IN A     63.245.209.72

> [ brendan@swift : 08:07:41 : ~ ]
> :) dig bugzilla.mozilla.org. | grep . | grep -v "^;"
> bugzilla.mozilla.org.   4       IN      CNAME   bugzilla-mozilla-org.geo.mozilla.com.
> bugzilla-mozilla-org.geo.mozilla.com. 1605 IN CNAME dyna-bugzilla.nslb.sj.mozilla.com.
> dyna-bugzilla.nslb.sj.mozilla.com. 544 IN A     63.245.209.72
Comment 68 Brendan Hide 2009-05-29 23:34:19 PDT
Um... maybe should have been more specific:
2. Prove that the wildcard NOT matching dots has tangibly improved security.
Comment 69 Wan-Teh Chang 2009-06-01 11:58:30 PDT
(In reply to comment #67)

You can set the environment variable NSS_USE_SHEXP_IN_CERT_NAME
to 1 before starting Firefox to get the old certificate name
matching behavior.  See

http://www.mozilla.org/projects/security/pki/nss/nss-3.12.3/nss-3.12.3-release-notes.html#new
Comment 70 Johnathan Nightingale [:johnath] 2009-07-02 06:02:39 PDT
*** Bug 501862 has been marked as a duplicate of this bug. ***
Comment 71 Daniel Veditz [:dveditz] 2009-07-15 23:54:33 PDT
Further in reply to comment 67: You make reasonable points (though not new ones) but a fixed bug is not the place to argue policy. For now we have decided that compliance with the RFC--or rather, consistent behavior amongst browsers--is safer for users if occasionally inconvenient for administrators.

If you want to argue for different behavior then the mailing list/newsgroup mozilla.dev.tech.crypto is the right place (or maybe the new mozilla.dev.security.policy?)
Comment 72 Kaspar Brand 2009-07-31 01:09:47 PDT
Can bug 500495 be unhidden, please? Moxie Marlinspike's cat is now out of the bag.
Comment 73 Samuel Sidler (old account; do not CC) 2009-07-31 02:22:53 PDT
Fixed for 1.9.0.13 by bug 500495.
Comment 74 georgi - hopefully not receiving bugspam 2009-07-31 07:44:47 PDT
> Moxie Marlinspike's cat is now out of the bag.

it will be interesting what will be blacklisted this time
Comment 75 georgi - hopefully not receiving bugspam 2009-07-31 08:07:41 PDT
> Moxie Marlinspike's cat is now out of the bag.

just out of curiousity, is the the relevant code FIPS certified ?
Comment 76 Nelson Bolyard (seldom reads bugmail) 2009-07-31 11:05:37 PDT
> just out of curiousity, is the the relevant code FIPS certified ?

LOL.  No.  DNS is entirely out of scope for FIPS-140.
Comment 77 juan becerra [:juanb] 2009-07-31 21:04:54 PDT
Nelson, could you help us verify this bug for Fx3.0.13?
Comment 78 Nelson Bolyard (seldom reads bugmail) 2009-07-31 21:12:25 PDT
Sure,
go visit https://swiftspirit.co.za.plesk01.glodns.net/ 
with both 3.0.12 and 3.0.13.
It should work with 3.0.12 and not 3.0.13.
Comment 79 juan becerra [:juanb] 2009-07-31 21:24:33 PDT
Created attachment 392043 [details]
3.0.12 vs 3.0.13

Verified per comment #78 with Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.13) Gecko/2009073021 Firefox/3.0.13

Thanks again, Nelson.
Comment 80 mozbug1 2009-08-05 09:56:42 PDT
Great. You've broken my website. Thanks a lot.
Comment 81 Nelson Bolyard (seldom reads bugmail) 2009-08-05 12:59:11 PDT
Yup, web sites with broken certs are now just as broken on Firefox as they
were with IE and Opera.
Comment 82 mozbug1 2009-08-05 13:12:09 PDT
A *.*.xxxx.xxx certificate is not broken.  Well it wasn't until now.
Comment 83 Nelson Bolyard (seldom reads bugmail) 2009-08-05 13:14:22 PDT
Read RFC 2818, and test with IE and Opera.
Comment 84 mozbug1 2009-08-05 13:19:37 PDT
I did read the rfc.  The rfc does not prohibit *.*.xxxx.xxx.  And while I knew my website was broken with IE I was expecting more from Firefox.  Since when do we look to IE for inspiration on how to do things?
Comment 85 Al Billings [:abillings] 2009-08-21 17:52:49 PDT
Verified per comment #78 with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14pre) Gecko/2009081305 GranParadiso/3.0.14pre (.NET CLR 3.5.30729).
Comment 86 Iain Wade 2009-08-26 06:12:51 PDT
Google is using a multi-level wildcard *.*.appspot.com certificate for App Engine.

It works in Safari, and was previously working in Firefox (up to 3.0.12).

I agree with Comment #53 (Nelson Bolyard) that the routine in question should be crafted specifically for HTTPS, so I fail to understand why RFCs for IMAP, POP3, ACAP, LDAP, NNTP or SMTP over TLS were even considered.

I agree with Comment #24 (mozbug1@jks.tupari.net) that the intent for restricting the wildcard character to left most component in other protocols was likely to restrict the wildcard matching to the left side of the hostname. *.* support would be in the spirit of that interpretation.

Would a patch tweaking the behaviour to allow multiple left-aligned wildcard components be considered?

I think it's quite important for shared hosting solutions, not just corporate intranets.
Comment 87 Jo Hermans 2010-04-20 03:49:00 PDT
*** Bug 560476 has been marked as a duplicate of this bug. ***

Note You need to log in before you can comment on or make changes to this bug.