You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2014/10/12 14:36:12 UTC

svn commit: r1631167 - in /httpcomponents/httpasyncclient/trunk/httpasyncclient/src: main/java/org/apache/http/nio/conn/ssl/SSLIOSessionStrategy.java test/java/org/apache/http/localserver/AbstractAsyncTest.java

Author: olegk
Date: Sun Oct 12 12:36:12 2014
New Revision: 1631167

URL: http://svn.apache.org/r1631167
Log:
Fixed broken hostname verififcation

Modified:
    httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/nio/conn/ssl/SSLIOSessionStrategy.java
    httpcomponents/httpasyncclient/trunk/httpasyncclient/src/test/java/org/apache/http/localserver/AbstractAsyncTest.java

Modified: httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/nio/conn/ssl/SSLIOSessionStrategy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/nio/conn/ssl/SSLIOSessionStrategy.java?rev=1631167&r1=1631166&r2=1631167&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/nio/conn/ssl/SSLIOSessionStrategy.java (original)
+++ httpcomponents/httpasyncclient/trunk/httpasyncclient/src/main/java/org/apache/http/nio/conn/ssl/SSLIOSessionStrategy.java Sun Oct 12 12:36:12 2014
@@ -28,13 +28,21 @@
 package org.apache.http.nio.conn.ssl;
 
 import java.io.IOException;
+import java.net.URL;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
 
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSession;
+import javax.security.auth.x500.X500Principal;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.http.HttpHost;
 import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
 import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
@@ -42,6 +50,7 @@ import org.apache.http.conn.ssl.DefaultH
 import org.apache.http.conn.ssl.SSLContexts;
 import org.apache.http.conn.ssl.StrictHostnameVerifier;
 import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.conn.util.PublicSuffixMatcher;
 import org.apache.http.conn.util.PublicSuffixMatcherLoader;
 import org.apache.http.nio.conn.SchemeIOSessionStrategy;
 import org.apache.http.nio.reactor.IOSession;
@@ -78,11 +87,39 @@ public class SSLIOSessionStrategy implem
         return s.split(" *, *");
     }
 
+    //TODO: remove after upgrade to HttpCore 4.4-beta2 or newer
+    private static volatile PublicSuffixMatcher DEFAULT_INSTANCE;
+
+    private static PublicSuffixMatcher getDefaultPublicSuffixMatcher() {
+        if (DEFAULT_INSTANCE == null) {
+            synchronized (PublicSuffixMatcherLoader.class) {
+                if (DEFAULT_INSTANCE == null){
+                    final URL url = PublicSuffixMatcherLoader.class.getResource(
+                            "/mozilla/public-suffix-list.txt");
+                    if (url != null) {
+                        try {
+                            DEFAULT_INSTANCE = PublicSuffixMatcherLoader.load(url);
+                        } catch (IOException ex) {
+                            // Should never happen
+                            final Log log = LogFactory.getLog(PublicSuffixMatcherLoader.class);
+                            if (log.isWarnEnabled()) {
+                                log.warn("Failure loading public suffix list from default resource", ex);
+                            }
+                        }
+                    } else {
+                        DEFAULT_INSTANCE = new PublicSuffixMatcher(Arrays.asList("com"), null);
+                    }
+                }
+            }
+        }
+        return DEFAULT_INSTANCE;
+    }
+
     /**
      * @since 4.1
      */
     public static HostnameVerifier getDefaultHostnameVerifier() {
-        return new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault());
+        return new DefaultHostnameVerifier(getDefaultPublicSuffixMatcher());
     }
 
     public static SSLIOSessionStrategy getDefaultStrategy() {
@@ -196,7 +233,13 @@ public class SSLIOSessionStrategy implem
             final HttpHost host,
             final IOSession iosession,
             final SSLSession sslsession) throws SSLException {
-        this.hostnameVerifier.verify(host.getHostName(), sslsession);
+        if (!this.hostnameVerifier.verify(host.getHostName(), sslsession)) {
+            final Certificate[] certs = sslsession.getPeerCertificates();
+            final X509Certificate x509 = (X509Certificate) certs[0];
+            final X500Principal x500Principal = x509.getSubjectX500Principal();
+            throw new SSLPeerUnverifiedException("Host name '" + host.getHostName() + "' does not match " +
+                    "the certificate subject provided by the peer (" + x500Principal.toString() + ")");
+        }
     }
 
     @Override

Modified: httpcomponents/httpasyncclient/trunk/httpasyncclient/src/test/java/org/apache/http/localserver/AbstractAsyncTest.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/httpasyncclient/src/test/java/org/apache/http/localserver/AbstractAsyncTest.java?rev=1631167&r1=1631166&r2=1631167&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/httpasyncclient/src/test/java/org/apache/http/localserver/AbstractAsyncTest.java (original)
+++ httpcomponents/httpasyncclient/trunk/httpasyncclient/src/test/java/org/apache/http/localserver/AbstractAsyncTest.java Sun Oct 12 12:36:12 2014
@@ -34,6 +34,7 @@ import org.apache.http.ExceptionLogger;
 import org.apache.http.HttpHost;
 import org.apache.http.config.Registry;
 import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.http.impl.nio.bootstrap.HttpServer;
 import org.apache.http.impl.nio.bootstrap.ServerBootstrap;
 import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
@@ -95,7 +96,11 @@ public abstract class AbstractAsyncTest 
         final RegistryBuilder<SchemeIOSessionStrategy> builder = RegistryBuilder.create();
         builder.register("http", NoopIOSessionStrategy.INSTANCE);
         if (this.scheme.equals(ProtocolScheme.https)) {
-            builder.register("https", new SSLIOSessionStrategy(SSLTestContexts.createClientSSLContext()));
+            builder.register("https", new SSLIOSessionStrategy(
+                    SSLTestContexts.createClientSSLContext(),
+                    // TODO: replace with the default hostname verifier
+                    // TODO: after upgrade to HttpCore 4.4-beta2 or newer
+                    NoopHostnameVerifier.INSTANCE));
         }
         final Registry<SchemeIOSessionStrategy> registry =  builder.build();
         final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);