hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1618867 - in /httpcomponents/httpclient/trunk: ./ httpclient/src/main/java/org/apache/http/conn/ssl/ httpclient/src/test/java/org/apache/http/conn/ssl/
Date Tue, 19 Aug 2014 14:09:31 GMT
Author: olegk
Date: Tue Aug 19 14:09:30 2014
New Revision: 1618867

URL: http://svn.apache.org/r1618867
Log:
Improved compliance with RFC 2818: default hostname verifier to ignore the common name of
the certificate subject if alternative subject names (dNSName or iPAddress) are present

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/main/java/org/apache/http/conn/ssl/DefaultHostnameVerifier.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=1618867&r1=1618866&r2=1618867&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Tue Aug 19 14:09:30 2014
@@ -1,6 +1,10 @@
-Changes isnce 4.4 ALPHA1
+Changes since 4.4 ALPHA1
 -------------------
 
+* Improved compliance with RFC 2818: default hostname verifier to ignore the common name
of the
+  certificate subject if alternative subject names (dNSName or iPAddress) are present.
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
 * [HTTPCLIENT-1540] Support delegated credentials (ISC_REQ_DELEGATE) by Native windows
   Negotiate/NTLM auth schemes.
   Contributed by Ka-Lok Fung <ka-lok.fung at sap.com>

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=1618867&r1=1618866&r2=1618867&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
Tue Aug 19 14:09:30 2014
@@ -140,20 +140,10 @@ public abstract class AbstractVerifier i
 
         final String cn = cns != null && cns.length > 0 ? cns[0] : null;
         final List<String> subjectAltList = subjectAlts != null && subjectAlts.length
> 0 ? Arrays.asList(subjectAlts) : null;
-        if (cn == null && subjectAltList == null) {
-            final String msg = "Certificate subject for <" + host + "> doesn't contain
a common name " +
-                    "and does not have alternative names";
-            throw new SSLException(msg);
-        }
+
         final String normalizedHost = InetAddressUtils.isIPv6Address(host) ?
                 DefaultHostnameVerifier.normaliseAddress(host.toLowerCase(Locale.ROOT)) :
host;
-        if (cn != null) {
-            final String normalizedCN = InetAddressUtils.isIPv6Address(cn) ?
-                    DefaultHostnameVerifier.normaliseAddress(cn) : cn;
-            if (matchIdentity(normalizedHost, normalizedCN, strictWithSubDomains)) {
-                return;
-            }
-        }
+
         if (subjectAltList != null) {
             for (String subjectAlt: subjectAltList) {
                 final String normalizedAltSubject = InetAddressUtils.isIPv6Address(subjectAlt)
?
@@ -162,19 +152,20 @@ public abstract class AbstractVerifier i
                     return;
                 }
             }
-        }
-        final StringBuilder buf = new StringBuilder();
-        buf.append("Certificate for <").append(host).append("> doesn't match ");
-        if (cn != null) {
-            buf.append("common name of the certificate subject [").append(cn).append("]");
-        }
-        if (subjectAltList != null) {
-            if (cn != null) {
-                buf.append(" or ");
+            throw new SSLException("Certificate for <" + host + "> doesn't match any
" +
+                    "of the subject alternative names: " + subjectAltList);
+        } else if (cn != null) {
+            final String normalizedCN = InetAddressUtils.isIPv6Address(cn) ?
+                    DefaultHostnameVerifier.normaliseAddress(cn) : cn;
+            if (matchIdentity(normalizedHost, normalizedCN, strictWithSubDomains)) {
+                return;
             }
-            buf.append(" any of the subject alternative names").append(subjectAltList);
+            throw new SSLException("Certificate for <" + host + "> doesn't match "
+
+                    "common name of the certificate subject: " + cn);
+        } else {
+            throw new SSLException("Certificate subject for <" + host + "> doesn't
contain " +
+                    "a common name and does not have alternative names");
         }
-        throw new SSLException(buf.toString());
     }
 
     private static boolean matchIdentity(final String host, final String identity, final
boolean strictWithSubDomains) {

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/DefaultHostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/DefaultHostnameVerifier.java?rev=1618867&r1=1618866&r2=1618867&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/DefaultHostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/DefaultHostnameVerifier.java
Tue Aug 19 14:09:30 2014
@@ -123,6 +123,10 @@ public final class DefaultHostnameVerifi
             // as fallback only when no subjectAlts are available
             final X500Principal subjectPrincipal = cert.getSubjectX500Principal();
             final String cn = extractCN(subjectPrincipal.getName(X500Principal.RFC2253));
+            if (cn == null) {
+                throw new SSLException("Certificate subject for <" + host + "> doesn't
contain " +
+                        "a common name and does not have alternative names");
+            }
             matchCN(host, cn);
         }
     }
@@ -135,7 +139,7 @@ public final class DefaultHostnameVerifi
             }
         }
         throw new SSLException("Certificate for <" + host + "> doesn't match any "
+
-                "of the subject alternative names " + subjectAlts);
+                "of the subject alternative names: " + subjectAlts);
     }
 
     static void matchIPv6Address(final String host, final List<String> subjectAlts)
throws SSLException {
@@ -148,7 +152,7 @@ public final class DefaultHostnameVerifi
             }
         }
         throw new SSLException("Certificate for <" + host + "> doesn't match any "
+
-                "of the subject alternative names " + subjectAlts);
+                "of the subject alternative names: " + subjectAlts);
     }
 
     static void matchDNSName(final String host, final List<String> subjectAlts) throws
SSLException {
@@ -159,13 +163,13 @@ public final class DefaultHostnameVerifi
             }
         }
         throw new SSLException("Certificate for <" + host + "> doesn't match any "
+
-                "of the subject alternative names " + subjectAlts);
+                "of the subject alternative names: " + subjectAlts);
     }
 
     static void matchCN(final String host, final String cn) throws SSLException {
         if (!matchIdentity(host, cn)) {
             throw new SSLException("Certificate for <" + host + "> doesn't match "
+
-                    "common name of the certificate subject [" + cn + "]");
+                    "common name of the certificate subject: " + cn);
         }
     }
 

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=1618867&r1=1618866&r2=1618867&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
Tue Aug 19 14:09:30 2014
@@ -74,8 +74,8 @@ public class TestHostnameVerifier {
 
         in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR);
         x509 = (X509Certificate) cf.generateCertificate(in);
-        DEFAULT.verify("foo.com", x509);
-        STRICT.verify("foo.com", x509);
+        exceptionPlease(DEFAULT, "foo.com", x509);
+        exceptionPlease(STRICT, "foo.com", x509);
         exceptionPlease(DEFAULT, "a.foo.com", x509);
         exceptionPlease(STRICT, "a.foo.com", x509);
         DEFAULT.verify("bar.com", x509);
@@ -85,8 +85,8 @@ public class TestHostnameVerifier {
 
         in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR_HANAKO);
         x509 = (X509Certificate) cf.generateCertificate(in);
-        DEFAULT.verify("foo.com", x509);
-        STRICT.verify("foo.com", x509);
+        exceptionPlease(DEFAULT, "foo.com", x509);
+        exceptionPlease(STRICT, "foo.com", x509);
         exceptionPlease(DEFAULT, "a.foo.com", x509);
         exceptionPlease(STRICT, "a.foo.com", x509);
         DEFAULT.verify("bar.com", x509);
@@ -159,11 +159,11 @@ public class TestHostnameVerifier {
         // try the foo.com variations
         exceptionPlease(DEFAULT, "foo.com", x509);
         exceptionPlease(STRICT, "foo.com", x509);
-        DEFAULT.verify("www.foo.com", x509);
-        STRICT.verify("www.foo.com", x509);
-        DEFAULT.verify("\u82b1\u5b50.foo.com", x509);
-        STRICT.verify("\u82b1\u5b50.foo.com", x509);
-        DEFAULT.verify("a.b.foo.com", x509);
+        exceptionPlease(DEFAULT, "www.foo.com", x509);
+        exceptionPlease(STRICT, "www.foo.com", x509);
+        exceptionPlease(DEFAULT, "\u82b1\u5b50.foo.com", x509);
+        exceptionPlease(STRICT, "\u82b1\u5b50.foo.com", x509);
+        exceptionPlease(DEFAULT, "a.b.foo.com", x509);
         exceptionPlease(STRICT, "a.b.foo.com", x509);
         // try the bar.com variations
         exceptionPlease(DEFAULT, "bar.com", x509);
@@ -174,19 +174,6 @@ public class TestHostnameVerifier {
         STRICT.verify("\u82b1\u5b50.bar.com", x509);
         DEFAULT.verify("a.b.bar.com", x509);
         exceptionPlease(STRICT, "a.b.bar.com", x509);
-        // try the \u82b1\u5b50.co.jp variations
-        /*
-           Java isn't extracting international subjectAlts properly.  (Or
-           OpenSSL isn't storing them properly).
-        */
-        //exceptionPlease( DEFAULT, "\u82b1\u5b50.co.jp", x509 );
-        //exceptionPlease( STRICT, "\u82b1\u5b50.co.jp", x509 );
-        //DEFAULT.verify("www.\u82b1\u5b50.co.jp", x509 );
-        //STRICT.verify("www.\u82b1\u5b50.co.jp", x509 );
-        //DEFAULT.verify("\u82b1\u5b50.\u82b1\u5b50.co.jp", x509 );
-        //STRICT.verify("\u82b1\u5b50.\u82b1\u5b50.co.jp", x509 );
-        //DEFAULT.verify("a.b.\u82b1\u5b50.co.jp", x509 );
-        //exceptionPlease(STRICT,"a.b.\u82b1\u5b50.co.jp", x509 );
 
         in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_VALUE_AVA);
         x509 = (X509Certificate) cf.generateCertificate(in);
@@ -206,11 +193,16 @@ public class TestHostnameVerifier {
         Assert.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("localhost", x509);
+            Assert.fail("SSLException should have been thrown");
+        } catch (final SSLException ex) {
+            // expected
+        }
+        try {
             verifier.verify("local.host", x509);
             Assert.fail("SSLException should have been thrown");
         } catch (final SSLException ex) {
@@ -296,7 +288,7 @@ public class TestHostnameVerifier {
         checkMatching(bhv, "s.a.gov.com", cns, alt, false); // OK, gov not 2TLD here
         checkMatching(shv, "s.a.gov.com", cns, alt, true); // no subdomain allowed
 
-        cns = new String []{"a*.gov.uk"}; // 2TLD check applies to wildcards
+        alt = new String []{"a*.gov.uk"}; // 2TLD check applies to wildcards
         checkMatching(bhv, "a.gov.uk", cns, alt, false); // OK
         checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD
 



Mime
View raw message