hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1778411 - in /httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl: DefaultHostnameVerifier.java SSLConnectionSocketFactory.java
Date Thu, 12 Jan 2017 10:08:41 GMT
Author: olegk
Date: Thu Jan 12 10:08:41 2017
New Revision: 1778411

URL: http://svn.apache.org/viewvc?rev=1778411&view=rev
Log:
HTTPCLIENT-1792: SSLConnectionSocketFactory to throw SSLPeerUnverifiedException with a better
error message when hostname verification fails

Modified:
    httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
    httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java

Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java?rev=1778411&r1=1778410&r2=1778411&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
Thu Jan 12 10:08:41 2017
@@ -46,6 +46,7 @@ import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSession;
 import javax.security.auth.x500.X500Principal;
 
@@ -65,10 +66,17 @@ import org.apache.logging.log4j.Logger;
 @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
 public final class DefaultHostnameVerifier implements HostnameVerifier {
 
-    enum TYPE { IPv4, IPv6, DNS }
+    enum HostNameType {
 
-    final static int DNS_NAME_TYPE        = 2;
-    final static int IP_ADDRESS_TYPE      = 7;
+        IPv4(7), IPv6(7), DNS(2);
+
+        final int subjectType;
+
+        HostNameType(final int subjectType) {
+            this.subjectType = subjectType;
+        }
+
+    }
 
     private final Logger log = LogManager.getLogger(getClass());
 
@@ -99,22 +107,10 @@ public final class DefaultHostnameVerifi
 
     public void verify(
             final String host, final X509Certificate cert) throws SSLException {
-        TYPE hostFormat = TYPE.DNS;
-        if (InetAddressUtils.isIPv4Address(host)) {
-            hostFormat = TYPE.IPv4;
-        } else {
-            String s = host;
-            if (s.startsWith("[") && s.endsWith("]")) {
-                s = host.substring(1, host.length() - 1);
-            }
-            if (InetAddressUtils.isIPv6Address(s)) {
-                hostFormat = TYPE.IPv6;
-            }
-        }
-        final int subjectType = hostFormat == TYPE.IPv4 || hostFormat == TYPE.IPv6 ? IP_ADDRESS_TYPE
: DNS_NAME_TYPE;
-        final List<String> subjectAlts = extractSubjectAlts(cert, subjectType);
+        final HostNameType hostType = determineHostFormat(host);
+        final List<String> subjectAlts = extractSubjectAlts(cert, hostType.subjectType);
         if (subjectAlts != null && !subjectAlts.isEmpty()) {
-            switch (hostFormat) {
+            switch (hostType) {
                 case IPv4:
                     matchIPAddress(host, subjectAlts);
                     break;
@@ -144,7 +140,7 @@ public final class DefaultHostnameVerifi
                 return;
             }
         }
-        throw new SSLException("Certificate for <" + host + "> doesn't match any "
+
+        throw new SSLPeerUnverifiedException("Certificate for <" + host + "> doesn't
match any " +
                 "of the subject alternative names: " + subjectAlts);
     }
 
@@ -157,7 +153,7 @@ public final class DefaultHostnameVerifi
                 return;
             }
         }
-        throw new SSLException("Certificate for <" + host + "> doesn't match any "
+
+        throw new SSLPeerUnverifiedException("Certificate for <" + host + "> doesn't
match any " +
                 "of the subject alternative names: " + subjectAlts);
     }
 
@@ -171,7 +167,7 @@ public final class DefaultHostnameVerifi
                 return;
             }
         }
-        throw new SSLException("Certificate for <" + host + "> doesn't match any "
+
+        throw new SSLPeerUnverifiedException("Certificate for <" + host + "> doesn't
match any " +
                 "of the subject alternative names: " + subjectAlts);
     }
 
@@ -180,7 +176,7 @@ public final class DefaultHostnameVerifi
         final String normalizedHost = host.toLowerCase(Locale.ROOT);
         final String normalizedCn = cn.toLowerCase(Locale.ROOT);
         if (!matchIdentityStrict(normalizedHost, normalizedCn, publicSuffixMatcher)) {
-            throw new SSLException("Certificate for <" + host + "> doesn't match "
+
+            throw new SSLPeerUnverifiedException("Certificate for <" + host + "> doesn't
match " +
                     "common name of the certificate subject: " + cn);
         }
     }
@@ -276,6 +272,21 @@ public final class DefaultHostnameVerifi
         }
     }
 
+    static HostNameType determineHostFormat(final String host) {
+        if (InetAddressUtils.isIPv4Address(host)) {
+            return HostNameType.IPv4;
+        } else {
+            String s = host;
+            if (s.startsWith("[") && s.endsWith("]")) {
+                s = host.substring(1, host.length() - 1);
+            }
+            if (InetAddressUtils.isIPv6Address(s)) {
+                return HostNameType.IPv6;
+            }
+        }
+        return HostNameType.DNS;
+    }
+
     static List<String> extractSubjectAlts(final X509Certificate cert, final int subjectType)
{
         Collection<List<?>> c = null;
         try {
@@ -300,6 +311,11 @@ public final class DefaultHostnameVerifi
         return subjectAltList;
     }
 
+    static List<String> extractSubjectAlts(final String host, final X509Certificate
cert) {
+        final HostNameType hostType = determineHostFormat(host);
+        return extractSubjectAlts(cert, hostType.subjectType);
+    }
+
     /*
      * Normalize IPv6 or DNS name.
      */

Modified: httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java?rev=1778411&r1=1778410&r2=1778411&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java
Thu Jan 12 10:08:41 2017
@@ -400,9 +400,9 @@ public class SSLConnectionSocketFactory
             if (!this.hostnameVerifier.verify(hostname, session)) {
                 final Certificate[] certs = session.getPeerCertificates();
                 final X509Certificate x509 = (X509Certificate) certs[0];
-                final X500Principal x500Principal = x509.getSubjectX500Principal();
-                throw new SSLPeerUnverifiedException("Host name '" + hostname + "' does not
match " +
-                        "the certificate subject provided by the peer (" + x500Principal.toString()
+ ")");
+                final List<String> subjectAlts = DefaultHostnameVerifier.extractSubjectAlts(hostname,
x509);
+                throw new SSLPeerUnverifiedException("Certificate for <" + hostname +
"> doesn't match any " +
+                        "of the subject alternative names: " + subjectAlts);
             }
             // verifyHostName() didn't blowup - good!
         } catch (final IOException iox) {



Mime
View raw message