You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by se...@apache.org on 2011/06/02 15:08:16 UTC

svn commit: r1130531 - in /httpcomponents/httpclient/trunk: RELEASE_NOTES.txt httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java

Author: sebb
Date: Thu Jun  2 13:08:15 2011
New Revision: 1130531

URL: http://svn.apache.org/viewvc?rev=1130531&view=rev
Log:
HTTPCLIENT-1097 BrowserCompatHostnameVerifier and StrictHostnameVerifier should handle wildcards in SSL certificates better.

Modified:
    httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java
    httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java

Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=1130531&r1=1130530&r2=1130531&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Thu Jun  2 13:08:15 2011
@@ -1,5 +1,8 @@
 Changes since 4.1.1
 
+* [HTTPCLIENT-1097] BrowserCompatHostnameVerifier and StrictHostnameVerifier should handle wildcards in SSL certificates better.
+  Contributed by Sebastian Bazley <sebb at apache.org>
+
 * [HTTPCLIENT-1092] If ClientPNames.VIRTUAL_HOST does not provide the port, derive it from the current request.
   Contributed by Sebastian Bazley <sebb at apache.org>
 

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java?rev=1130531&r1=1130530&r2=1130531&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java Thu Jun  2 13:08:15 2011
@@ -197,13 +197,21 @@ public abstract class AbstractVerifier i
             // The CN better have at least two dots if it wants wildcard
             // action.  It also can't be [*.co.uk] or [*.co.jp] or
             // [*.org.uk], etc...
-            boolean doWildcard = cn.startsWith("*.") &&
-                                 cn.lastIndexOf('.') >= 0 &&
+            String parts[] = cn.split("\\.");
+            boolean doWildcard = parts.length >= 3 &&
+                                 parts[0].endsWith("*") &&
                                  acceptableCountryWildcard(cn) &&
                                  !isIPAddress(host);
 
             if(doWildcard) {
-                match = hostName.endsWith(cn.substring(1));
+                if (parts[0].length() > 1) { // e.g. server*
+                    String prefix = parts[0].substring(0, parts.length-2); // e.g. server
+                    String suffix = cn.substring(parts[0].length()); // skip wildcard part from cn
+                    String hostSuffix = hostName.substring(prefix.length()); // skip wildcard part from host
+                    match = hostName.startsWith(prefix) && hostSuffix.endsWith(suffix);
+                } else {
+                    match = hostName.endsWith(cn.substring(1));                    
+                }
                 if(match && strictWithSubDomains) {
                     // If we're in strict mode, then [*.foo.com] is not
                     // allowed to match [a.b.foo.com]
@@ -222,18 +230,11 @@ public abstract class AbstractVerifier i
     }
 
     public static boolean acceptableCountryWildcard(String cn) {
-        int cnLen = cn.length();
-        if(cnLen >= 7 && cnLen <= 9) {
-            // Look for the '.' in the 3rd-last position:
-            if(cn.charAt(cnLen - 3) == '.') {
-                // Trim off the [*.] and the [.XX].
-                String s = cn.substring(2, cnLen - 3);
-                // And test against the sorted array of bad 2lds:
-                int x = Arrays.binarySearch(BAD_COUNTRY_2LDS, s);
-                return x < 0;
-            }
+        String parts[] = cn.split("\\.");
+        if (parts.length != 3 || parts[2].length() != 2) {
+            return true; // it's not an attempt to wildcard a 2TLD within a country code
         }
-        return true;
+        return Arrays.binarySearch(BAD_COUNTRY_2LDS, parts[1]) < 0;
     }
 
     public static String[] getCNs(X509Certificate cert) {

Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java?rev=1130531&r1=1130530&r2=1130531&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java Thu Jun  2 13:08:15 2011
@@ -36,7 +36,6 @@ import java.util.Arrays;
 import javax.net.ssl.SSLException;
 
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -301,7 +300,6 @@ public class TestHostnameVerifier {
     }
 
     @Test
-    @Ignore("not yet implemented")
     public void HTTPCLIENT_1097() {
         String cns[];
         String alt[] = {};
@@ -312,8 +310,8 @@ public class TestHostnameVerifier {
         checkMatching(bhv, "a.b.c", cns, alt, false); // OK
         checkMatching(shv, "a.b.c", cns, alt, false); // OK
 
-        checkMatching(bhv, "s.a.b.c", cns, alt, false); // OK
-        checkMatching(shv, "s.a.b.c", cns, alt, true); // subdomain not OK
+        checkMatching(bhv, "a.a.b.c", cns, alt, false); // OK
+        checkMatching(shv, "a.a.b.c", cns, alt, true); // subdomain not OK
 
         checkWildcard("s*.co.uk", false); // 2 character TLD, invalid 2TLD
         checkWildcard("s*.gov.uk", false); // 2 character TLD, invalid 2TLD