hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r709402 - in /httpcomponents/httpclient/trunk: ./ module-client/src/main/java/org/apache/http/conn/ssl/ module-client/src/test/java/org/apache/http/conn/ssl/
Date Fri, 31 Oct 2008 13:08:23 GMT
Author: olegk
Date: Fri Oct 31 06:08:23 2008
New Revision: 709402

URL: http://svn.apache.org/viewvc?rev=709402&view=rev
Log:
HTTPCLIENT-803: Fixed bug in SSL host verifier implementations causing the SSL certificate
to be rejected as invalid if the connection is established using an IP address

Modified:
    httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
    httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java
    httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/CertificatesToPlayWith.java
    httpcomponents/httpclient/trunk/module-client/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=709402&r1=709401&r2=709402&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Fri Oct 31 06:08:23 2008
@@ -1,6 +1,11 @@
 Changes since 4.0 beta 1
 -------------------
 
+* [HTTPCLIENT-803] Fixed bug in SSL host verifier implementations 
+  causing the SSL certificate to be rejected as invalid if the connection 
+  is established using an IP address.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
 * [HTTPCLIENT-806] DefaultHttpMethodRetryHandler will no longer retry
   on ConnectExceptions.
   Contributed by Oleg Kalnichevski <olegk at apache.org>

Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java?rev=709402&r1=709401&r2=709402&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java
Fri Oct 31 06:08:23 2008
@@ -131,6 +131,7 @@
         verify(host, x509);
     }
 
+    @Deprecated
     public final boolean verify(String host, SSLSession session) {
         try {
             Certificate[] certs = session.getPeerCertificates();
@@ -146,7 +147,7 @@
     public final void verify(String host, X509Certificate cert)
           throws SSLException {
         String[] cns = getCNs(cert);
-        String[] subjectAlts = getDNSSubjectAlts(cert);
+        String[] subjectAlts = getSubjectAlts(cert, host);
         verify(host, cns, subjectAlts);
     }
 
@@ -201,7 +202,7 @@
             boolean doWildcard = cn.startsWith("*.") &&
                                  cn.lastIndexOf('.') >= 0 &&
                                  acceptableCountryWildcard(cn) &&
-                                 !InetAddressUtils.isIPv4Address(host);
+                                 !isIPAddress(host);
 
             if(doWildcard) {
                 match = hostName.endsWith(cn.substring(1));
@@ -279,22 +280,23 @@
         }
     }
 
-
     /**
-     * Extracts the array of SubjectAlt DNS names from an X509Certificate.
+     * Extracts the array of SubjectAlt DNS or IP names from an X509Certificate.
      * Returns null if there aren't any.
-     * <p/>
-     * Note:  Java doesn't appear able to extract international characters
-     * from the SubjectAlts.  It can only extract international characters
-     * from the CN field.
-     * <p/>
-     * (Or maybe the version of OpenSSL I'm using to test isn't storing the
-     * international characters correctly in the SubjectAlts?).
      *
      * @param cert X509Certificate
-     * @return Array of SubjectALT DNS names stored in the certificate.
+     * @param hostname
+     * @return Array of SubjectALT DNS or IP names stored in the certificate.
      */
-    public static String[] getDNSSubjectAlts(X509Certificate cert) {
+    private static String[] getSubjectAlts(
+            final X509Certificate cert, final String hostname) {
+        int subjectType;
+        if (isIPAddress(hostname)) {
+            subjectType = 7;
+        } else {
+            subjectType = 2;
+        }
+        
         LinkedList<String> subjectAltList = new LinkedList<String>();
         Collection<List<?>> c = null;
         try {
@@ -308,8 +310,7 @@
             for (List<?> aC : c) {
                 List<?> list = aC;
                 int type = ((Integer) list.get(0)).intValue();
-                // If type is 2, then we've got a dNSName
-                if (type == 2) {
+                if (type == subjectType) {
                     String s = (String) list.get(1);
                     subjectAltList.add(s);
                 }
@@ -325,6 +326,24 @@
     }
 
     /**
+     * Extracts the array of SubjectAlt DNS names from an X509Certificate.
+     * Returns null if there aren't any.
+     * <p/>
+     * Note:  Java doesn't appear able to extract international characters
+     * from the SubjectAlts.  It can only extract international characters
+     * from the CN field.
+     * <p/>
+     * (Or maybe the version of OpenSSL I'm using to test isn't storing the
+     * international characters correctly in the SubjectAlts?).
+     *
+     * @param cert X509Certificate
+     * @return Array of SubjectALT DNS names stored in the certificate.
+     */
+    public static String[] getDNSSubjectAlts(X509Certificate cert) {
+        return getSubjectAlts(cert, null);
+    }
+
+    /**
      * Counts the number of dots "." in a string.
      * @param s  string to count dots from
      * @return  number of dots
@@ -339,4 +358,10 @@
         return count;
     }
     
+    private static boolean isIPAddress(final String hostname) {
+        return hostname != null && 
+            (InetAddressUtils.isIPv4Address(hostname) || 
+                    InetAddressUtils.isIPv6Address(hostname));
+    }
+    
 }

Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/CertificatesToPlayWith.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/CertificatesToPlayWith.java?rev=709402&r1=709401&r2=709402&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/CertificatesToPlayWith.java
(original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/CertificatesToPlayWith.java
Fri Oct 31 06:08:23 2008
@@ -450,4 +450,30 @@
           "001853788f1b5ccbf9affb4c52c9d2efdb8aab0183d86735b32737fb4e79" +
           "2b8a9c7d91c7d175ae";
 
+    /**
+     * subjectAlt=IP Address:127.0.0.1, email:oleg@ural.ru, DNS:localhost.localdomain
+     */
+    public final static byte[] X509_MULTIPLE_SUBJECT_ALT = (
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDcTCCAtqgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMQswCQYDVQQGEwJDSDEL\n" +
+        "MAkGA1UECBMCWkgxDzANBgNVBAcTBlp1cmljaDETMBEGA1UEAxMKTXkgVGVzdCBD\n" +
+        "QTAeFw0wODEwMzExMTU3NDVaFw0wOTEwMzExMTU3NDVaMGkxCzAJBgNVBAYTAkNI\n" +
+        "MRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdV\n" +
+        "bmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwggG4\n" +
+        "MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/\n" +
+        "gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQ\n" +
+        "IsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZ\n" +
+        "ndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5\n" +
+        "eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbh\n" +
+        "PBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8G\n" +
+        "kotmXoB7VSVkAUw7/s9JKgOBhQACgYEA6ogAb/YLM1Rz9AoXKW4LA70VtFf7Mqqp\n" +
+        "divdu9f72WQc1vMKo1YMf3dQadkMfBYRvAAa1IXDnoiFCHhXnVRkWkoUBJyNebLB\n" +
+        "N92CZc0RVFZiMFgQMEh8UldnvAIi4cBk0/YuN3BGl4MzmquVIGrFovdWGqeaveOu\n" +
+        "Xcu4lKGJNiqjODA2MDQGA1UdEQQtMCuHBH8AAAGBDG9sZWdAdXJhbC5ydYIVbG9j\n" +
+        "YWxob3N0LmxvY2FsZG9tYWluMA0GCSqGSIb3DQEBBQUAA4GBAIgEwIoCSRkU3O7K\n" +
+        "USYaOYyfJB9hsvs6YpClvYXiQ/5kPGARP60pM62v4wC7wI9shEizokIAxY2+O3cC\n" +
+        "vwuJhNYaa2FJMELIwRN3XES8X8R6JHWbPaRjaAAPhczuEd8SZYy8yiVLmJTgw0gH\n" +
+        "BSW775NHlkjsscFVgXkNf0PobqJ9\n" +
+        "-----END CERTIFICATE-----").getBytes();
+    
 }

Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java?rev=709402&r1=709401&r2=709402&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java
Fri Oct 31 06:08:23 2008
@@ -210,6 +210,38 @@
         //exceptionPlease(STRICT,"a.b.\u82b1\u5b50.co.jp", x509 );
     }
 
+    public void testSubjectAlt() throws Exception {
+        X509HostnameVerifier DEFAULT = new BrowserCompatHostnameVerifier();
+        X509HostnameVerifier STRICT = new StrictHostnameVerifier();
+        X509HostnameVerifier ALLOW_ALL = new AllowAllHostnameVerifier();
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        InputStream in = new ByteArrayInputStream(X509_MULTIPLE_SUBJECT_ALT);
+        X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
+        
+        X509HostnameVerifier verifier = SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
+        
+        assertEquals("CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=CH",

+                x509.getSubjectDN().getName());
+        
+        verifier.verify("localhost", x509);
+        verifier.verify("localhost.localdomain", x509);
+        verifier.verify("127.0.0.1", x509);
+        
+        try {
+            verifier.verify("local.host", x509);
+            fail("SSLException should have been thrown");
+        } catch (SSLException ex) {
+            // expected
+        }
+        try {
+            verifier.verify("127.0.0.2", x509);
+            fail("SSLException should have been thrown");
+        } catch (SSLException ex) {
+            // expected
+        }
+        
+    }
+    
     private void exceptionPlease(X509HostnameVerifier hv, String host,
                                  X509Certificate x509) {
         try {



Mime
View raw message