Bug 903885, fix IDNA wildcard handling v4, r=kaie
authorWan-Teh Chang <wtc@google.com>
Tue, 25 Feb 2014 18:17:08 +0100 (2014-02-25)
changeset 11046 2ffa40a3ff5584139c58fe65e44f788daf239aef
parent 11045 15ea62260c21d83e1ada26019f437833cbb0c6f5
child 11047 a96aef4ed565ad7b4a150e40c96ea4502c694298
push id309
push userkaie@kuix.de
push dateTue, 25 Feb 2014 17:17:15 +0000 (2014-02-25)
reviewerskaie
bugs903885
Bug 903885, fix IDNA wildcard handling v4, r=kaie
lib/certdb/certdb.c
--- a/lib/certdb/certdb.c
+++ b/lib/certdb/certdb.c
@@ -1376,37 +1376,36 @@ cert_TestHostName(char * cn, const char 
 		rv = SECSuccess;
 	    } else {
 		PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
 		rv = SECFailure;
 	    }
 	    return rv;
 	}
     } else {
-	/* New approach conforms to RFC 2818. */
+	/* New approach conforms to RFC 6125. */
 	char *wildcard    = PORT_Strchr(cn, '*');
 	char *firstcndot  = PORT_Strchr(cn, '.');
 	char *secondcndot = firstcndot ? PORT_Strchr(firstcndot+1, '.') : NULL;
 	char *firsthndot  = PORT_Strchr(hn, '.');
-	/* RFC 6125 IDN matching */
-	int firstace      = PORT_Strncasecmp('xn--', cn, 4);
 
 	/* For a cn pattern to be considered valid, the wildcard character...
 	 * - may occur only in a DNS name with at least 3 components, and
 	 * - may occur only as last character in the first component, and
 	 * - may be preceded by additional characters, and
-	 * - must not be preceded by an IDN ACE prefix (xn--)
+	 * - must not be preceded by an IDNA ACE prefix (xn--)
 	 */
 	if (wildcard && secondcndot && secondcndot[1] && firsthndot 
-	    && firstcndot  - wildcard  == 1
-	    && secondcndot - firstcndot > 1
-	    && PORT_Strrchr(cn, '*') == wildcard
+	    && firstcndot  - wildcard  == 1 /* no chars between * and . */
+	    && secondcndot - firstcndot > 1 /* not .. */
+	    && PORT_Strrchr(cn, '*') == wildcard /* only one wildcard in cn */
 	    && !PORT_Strncasecmp(cn, hn, wildcard - cn)
 	    && !PORT_Strcasecmp(firstcndot, firsthndot)
-	    && firstace != 0) {
+	       /* If hn starts with xn--, then cn must start with wildcard */
+	    && (PORT_Strncasecmp(hn, "xn--", 4) || wildcard == cn)) {
 	    /* valid wildcard pattern match */
 	    return SECSuccess;
 	}
     }
     /* String cn has no wildcard or shell expression.  
      * Compare entire string hn with cert name. 
      */
     if (PORT_Strcasecmp(hn, cn) == 0) {