hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1616758 - in /httpcomponents/httpclient/trunk/httpclient/src: examples/org/apache/http/examples/client/ main/java/org/apache/http/conn/ssl/ main/java/org/apache/http/impl/client/ test/java/org/apache/http/conn/ssl/
Date Fri, 08 Aug 2014 14:00:55 GMT
Author: olegk
Date: Fri Aug  8 14:00:55 2014
New Revision: 1616758

URL: http://svn.apache.org/r1616758
Log:
 Deprecated X509HostnameVerifier interface in favor of standard javax.net.ssl.HostnameVerifier

Added:
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/NoopHostnameVerifier.java
      - copied, changed from r1616688, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java
Removed:
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractBaseHostnameVerifier.java
Modified:
    httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java
    httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractCommonHostnameVerifier.java
    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/AllowAllHostnameVerifier.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java
    httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java

Modified: httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java
Fri Aug  8 14:00:55 2014
@@ -60,18 +60,16 @@ import org.apache.http.conn.ManagedHttpC
 import org.apache.http.conn.routing.HttpRoute;
 import org.apache.http.conn.socket.ConnectionSocketFactory;
 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLContexts;
-import org.apache.http.conn.ssl.X509HostnameVerifier;
 import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
 import org.apache.http.impl.conn.DefaultHttpResponseParser;
 import org.apache.http.impl.conn.DefaultHttpResponseParserFactory;
+import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.http.impl.conn.SystemDefaultDnsResolver;
 import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
@@ -141,14 +139,12 @@ public class ClientConfiguration {
         // SSL context for secure connections can be created either based on
         // system or application specific properties.
         SSLContext sslcontext = SSLContexts.createSystemDefault();
-        // Use custom hostname verifier to customize SSL hostname verification.
-        X509HostnameVerifier hostnameVerifier = new BrowserCompatHostnameVerifier();
 
         // Create a registry of custom connection socket factories for supported
         // protocol schemes.
         Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
             .register("http", PlainConnectionSocketFactory.INSTANCE)
-            .register("https", new SSLConnectionSocketFactory(sslcontext, hostnameVerifier))
+            .register("https", new SSLConnectionSocketFactory(sslcontext))
             .build();
 
         // Use custom DNS resolver to override the system DNS resolution.

Modified: httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java
Fri Aug  8 14:00:55 2014
@@ -35,8 +35,8 @@ import javax.net.ssl.SSLContext;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.ssl.SSLContexts;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLContexts;
 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
@@ -66,7 +66,7 @@ public class ClientCustomSSL {
                 sslcontext,
                 new String[] { "TLSv1" },
                 null,
-                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
         CloseableHttpClient httpclient = HttpClients.custom()
                 .setSSLSocketFactory(sslsf)
                 .build();

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractCommonHostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractCommonHostnameVerifier.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractCommonHostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractCommonHostnameVerifier.java
Fri Aug  8 14:00:55 2014
@@ -29,6 +29,7 @@ package org.apache.http.conn.ssl;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
@@ -46,7 +47,9 @@ import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
+import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -54,7 +57,7 @@ import org.apache.http.annotation.Immuta
 import org.apache.http.conn.util.InetAddressUtils;
 
 /**
- * Abstract base class for all standard {@link org.apache.http.conn.ssl.X509HostnameVerifier}
+ * Abstract base class for all standard {@link javax.net.ssl.HostnameVerifier}
  * implementations that provides methods to extract Common Name (CN) and alternative subjects
  * (subjectAlt) from {@link java.security.cert.X509Certificate} being validated as well
  * as {@link #verify(String, String[], String[], boolean)} method that implements common
@@ -63,7 +66,7 @@ import org.apache.http.conn.util.InetAdd
  * @since 4.4
  */
 @Immutable
-public abstract class AbstractCommonHostnameVerifier extends AbstractBaseHostnameVerifier
{
+public abstract class AbstractCommonHostnameVerifier implements HostnameVerifier {
 
     /**
      * This contains a list of 2nd-level domains that aren't allowed to
@@ -87,14 +90,30 @@ public abstract class AbstractCommonHost
     private final Log log = LogFactory.getLog(getClass());
 
     @Override
-    public final void verify(final String host, final X509Certificate cert)
-          throws SSLException {
+    public final boolean verify(final String host, final SSLSession session) {
+        try {
+            final Certificate[] certs = session.getPeerCertificates();
+            final X509Certificate x509 = (X509Certificate) certs[0];
+            verify(host, x509);
+            return true;
+        } catch(final SSLException ex) {
+            if (log.isDebugEnabled()) {
+                log.debug(ex.getMessage(), ex);
+            }
+            return false;
+        }
+    }
+
+    public final void verify(
+            final String host, final X509Certificate cert) throws SSLException {
         final String subjectPrincipal = cert.getSubjectX500Principal().toString();
         final String[] cns = extractCNs(subjectPrincipal);
         final String[] subjectAlts = extractSubjectAlts(cert, host);
         verify(host, cns, subjectAlts);
     }
 
+    public abstract void verify(String host, String[] cns, String[] subjectAlts) throws SSLException;
+
     public final void verify(final String host, final String[] cns,
                              final String[] subjectAlts,
                              final boolean strictWithSubDomains)

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=1616758&r1=1616757&r2=1616758&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
Fri Aug  8 14:00:55 2014
@@ -27,9 +27,16 @@
 
 package org.apache.http.conn.ssl;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.apache.http.util.Args;
 
 /**
  * Abstract base class for all standard {@link X509HostnameVerifier}
@@ -37,11 +44,57 @@ import javax.net.ssl.SSLException;
  *
  * @since 4.0
  *
- * @deprecated (4.4) use {@link AbstractBaseHostnameVerifier} or
- *  {@link org.apache.http.conn.ssl.AbstractCommonHostnameVerifier}
+ * @deprecated (4.4) use {@link javax.net.ssl.HostnameVerifier} or
+ *  {@link org.apache.http.conn.ssl.AbstractCommonHostnameVerifier}.
  */
 @Deprecated
-public abstract class AbstractVerifier extends AbstractCommonHostnameVerifier {
+public abstract class AbstractVerifier extends AbstractCommonHostnameVerifier implements
X509HostnameVerifier {
+
+    @Override
+    public final void verify(final String host, final SSLSocket ssl)
+            throws IOException {
+        Args.notNull(host, "Host");
+        SSLSession session = ssl.getSession();
+        if(session == null) {
+            // In our experience this only happens under IBM 1.4.x when
+            // spurious (unrelated) certificates show up in the server'
+            // chain.  Hopefully this will unearth the real problem:
+            final InputStream in = ssl.getInputStream();
+            in.available();
+            /*
+              If you're looking at the 2 lines of code above because
+              you're running into a problem, you probably have two
+              options:
+
+                #1.  Clean up the certificate chain that your server
+                     is presenting (e.g. edit "/etc/apache2/server.crt"
+                     or wherever it is your server's certificate chain
+                     is defined).
+
+                                           OR
+
+                #2.   Upgrade to an IBM 1.5.x or greater JVM, or switch
+                      to a non-IBM JVM.
+            */
+
+            // If ssl.getInputStream().available() didn't cause an
+            // exception, maybe at least now the session is available?
+            session = ssl.getSession();
+            if(session == null) {
+                // If it's still null, probably a startHandshake() will
+                // unearth the real problem.
+                ssl.startHandshake();
+
+                // Okay, if we still haven't managed to cause an exception,
+                // might as well go for the NPE.  Or maybe we're okay now?
+                session = ssl.getSession();
+            }
+        }
+
+        final Certificate[] certs = session.getPeerCertificates();
+        final X509Certificate x509 = (X509Certificate) certs[0];
+        verify(host, x509);
+    }
 
     public static String[] getCNs(final X509Certificate cert) {
         final String subjectPrincipal = cert.getSubjectX500Principal().toString();

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java
Fri Aug  8 14:00:55 2014
@@ -35,7 +35,10 @@ import org.apache.http.annotation.Immuta
  *
  *
  * @since 4.0
+ *
+ * @deprecated (4.4) Use {@link org.apache.http.conn.ssl.NoopHostnameVerifier}
  */
+@Deprecated
 @Immutable
 public class AllowAllHostnameVerifier extends AbstractVerifier {
 

Copied: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/NoopHostnameVerifier.java
(from r1616688, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/NoopHostnameVerifier.java?p2=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/NoopHostnameVerifier.java&p1=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java&r1=1616688&r2=1616758&rev=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/NoopHostnameVerifier.java
Fri Aug  8 14:00:55 2014
@@ -27,31 +27,30 @@
 
 package org.apache.http.conn.ssl;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
 import org.apache.http.annotation.Immutable;
 
 /**
- * The ALLOW_ALL HostnameVerifier essentially turns hostname verification
+ * The NO_OP HostnameVerifier essentially turns hostname verification
  * off. This implementation is a no-op, and never throws the SSLException.
  *
- *
- * @since 4.0
+ * @since 4.4
  */
 @Immutable
-public class AllowAllHostnameVerifier extends AbstractVerifier {
+public class NoopHostnameVerifier implements HostnameVerifier {
 
-    public static final AllowAllHostnameVerifier INSTANCE = new AllowAllHostnameVerifier();
+    public static final NoopHostnameVerifier INSTANCE = new NoopHostnameVerifier();
 
     @Override
-    public final void verify(
-            final String host,
-            final String[] cns,
-            final String[] subjectAlts) {
-        // Allow everything - so never blowup.
+    public boolean verify(final String s, final SSLSession sslSession) {
+        return true;
     }
 
     @Override
     public final String toString() {
-        return "ALLOW_ALL";
+        return "NO_OP";
     }
 
 }

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.java
Fri Aug  8 14:00:55 2014
@@ -27,6 +27,22 @@
 
 package org.apache.http.conn.ssl;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.security.auth.x500.X500Principal;
+
 import org.apache.http.HttpHost;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
@@ -34,13 +50,6 @@ import org.apache.http.protocol.HttpCont
 import org.apache.http.util.Args;
 import org.apache.http.util.TextUtils;
 
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-
 /**
  * Layered socket factory for TLS/SSL connections.
  * <p>
@@ -121,16 +130,26 @@ public class SSLConnectionSocketFactory 
     public static final String SSL   = "SSL";
     public static final String SSLV2 = "SSLv2";
 
+    @Deprecated
     public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER
         = AllowAllHostnameVerifier.INSTANCE;
 
+    @Deprecated
     public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
         = BrowserCompatHostnameVerifier.INSTANCE;
 
+    @Deprecated
     public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
         = StrictHostnameVerifier.INSTANCE;
 
     /**
+     * @since 4.4
+     */
+    public static HostnameVerifier getDefaultHostnameVerifier() {
+        return BrowserCompatHostnameVerifier.INSTANCE;
+    }
+
+    /**
      * Obtains default SSL socket factory with an SSL context based on the standard JSSE
      * trust material (<code>cacerts</code> file in the security properties directory).
      * System properties are not taken into consideration.
@@ -138,9 +157,7 @@ public class SSLConnectionSocketFactory 
      * @return default SSL socket factory
      */
     public static SSLConnectionSocketFactory getSocketFactory() throws SSLInitializationException
{
-        return new SSLConnectionSocketFactory(
-            SSLContexts.createDefault(),
-            BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+        return new SSLConnectionSocketFactory(SSLContexts.createDefault(), getDefaultHostnameVerifier());
     }
 
     private static String[] split(final String s) {
@@ -164,24 +181,34 @@ public class SSLConnectionSocketFactory 
             (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(),
             split(System.getProperty("https.protocols")),
             split(System.getProperty("https.cipherSuites")),
-            BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+            getDefaultHostnameVerifier());
     }
 
     private final javax.net.ssl.SSLSocketFactory socketfactory;
-    private final X509HostnameVerifier hostnameVerifier;
+    private final HostnameVerifier hostnameVerifier;
     private final String[] supportedProtocols;
     private final String[] supportedCipherSuites;
 
     public SSLConnectionSocketFactory(final SSLContext sslContext) {
-        this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
+        this(sslContext, getDefaultHostnameVerifier());
     }
 
+    /**
+     * @deprecated (4.4) Use {@link #SSLConnectionSocketFactory(javax.net.ssl.SSLContext,
+     *   javax.net.ssl.HostnameVerifier)}
+     */
+    @Deprecated
     public SSLConnectionSocketFactory(
             final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) {
         this(Args.notNull(sslContext, "SSL context").getSocketFactory(),
                 null, null, hostnameVerifier);
     }
 
+    /**
+     * @deprecated (4.4) Use {@link #SSLConnectionSocketFactory(javax.net.ssl.SSLContext,
+     *   String[], String[], javax.net.ssl.HostnameVerifier)}
+     */
+    @Deprecated
     public SSLConnectionSocketFactory(
             final SSLContext sslContext,
             final String[] supportedProtocols,
@@ -191,21 +218,72 @@ public class SSLConnectionSocketFactory 
                 supportedProtocols, supportedCipherSuites, hostnameVerifier);
     }
 
+    /**
+     * @deprecated (4.4) Use {@link #SSLConnectionSocketFactory(javax.net.ssl.SSLSocketFactory,
+     *   javax.net.ssl.HostnameVerifier)}
+     */
+    @Deprecated
     public SSLConnectionSocketFactory(
             final javax.net.ssl.SSLSocketFactory socketfactory,
             final X509HostnameVerifier hostnameVerifier) {
         this(socketfactory, null, null, hostnameVerifier);
     }
 
+    /**
+     * @deprecated (4.4) Use {@link #SSLConnectionSocketFactory(javax.net.ssl.SSLSocketFactory,
+     *   String[], String[], javax.net.ssl.HostnameVerifier)}
+     */
+    @Deprecated
     public SSLConnectionSocketFactory(
             final javax.net.ssl.SSLSocketFactory socketfactory,
             final String[] supportedProtocols,
             final String[] supportedCipherSuites,
             final X509HostnameVerifier hostnameVerifier) {
+        this(socketfactory, supportedProtocols, supportedCipherSuites, (HostnameVerifier)
hostnameVerifier);
+    }
+
+    /**
+     * @since 4.4
+     */
+    public SSLConnectionSocketFactory(
+            final SSLContext sslContext, final HostnameVerifier hostnameVerifier) {
+        this(Args.notNull(sslContext, "SSL context").getSocketFactory(),
+                null, null, hostnameVerifier);
+    }
+
+    /**
+     * @since 4.4
+     */
+    public SSLConnectionSocketFactory(
+            final SSLContext sslContext,
+            final String[] supportedProtocols,
+            final String[] supportedCipherSuites,
+            final HostnameVerifier hostnameVerifier) {
+        this(Args.notNull(sslContext, "SSL context").getSocketFactory(),
+                supportedProtocols, supportedCipherSuites, hostnameVerifier);
+    }
+
+    /**
+     * @since 4.4
+     */
+    public SSLConnectionSocketFactory(
+            final javax.net.ssl.SSLSocketFactory socketfactory,
+            final HostnameVerifier hostnameVerifier) {
+        this(socketfactory, null, null, hostnameVerifier);
+    }
+
+    /**
+     * @since 4.4
+     */
+    public SSLConnectionSocketFactory(
+            final javax.net.ssl.SSLSocketFactory socketfactory,
+            final String[] supportedProtocols,
+            final String[] supportedCipherSuites,
+            final HostnameVerifier hostnameVerifier) {
         this.socketfactory = Args.notNull(socketfactory, "SSL socket factory");
         this.supportedProtocols = supportedProtocols;
         this.supportedCipherSuites = supportedCipherSuites;
-        this.hostnameVerifier = hostnameVerifier != null ? hostnameVerifier : BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
+        this.hostnameVerifier = hostnameVerifier != null ? hostnameVerifier : getDefaultHostnameVerifier();
     }
 
     /**
@@ -281,13 +359,35 @@ public class SSLConnectionSocketFactory 
         return sslsock;
     }
 
-    X509HostnameVerifier getHostnameVerifier() {
-        return this.hostnameVerifier;
-    }
-
     private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException
{
         try {
-            this.hostnameVerifier.verify(hostname, sslsock);
+            SSLSession session = sslsock.getSession();
+            if (session == null) {
+                // In our experience this only happens under IBM 1.4.x when
+                // spurious (unrelated) certificates show up in the server'
+                // chain.  Hopefully this will unearth the real problem:
+                final InputStream in = sslsock.getInputStream();
+                in.available();
+                // If ssl.getInputStream().available() didn't cause an
+                // exception, maybe at least now the session is available?
+                session = sslsock.getSession();
+                if (session == null) {
+                    // If it's still null, probably a startHandshake() will
+                    // unearth the real problem.
+                    sslsock.startHandshake();
+                    session = sslsock.getSession();
+                }
+            }
+            if (session == null) {
+                throw new SSLHandshakeException("SSL session not available");
+            }
+            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()
+ ")");
+            }
             // verifyHostName() didn't blowup - good!
         } catch (final IOException iox) {
             // close the socket before re-throwing the exception

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.java
Fri Aug  8 14:00:55 2014
@@ -41,7 +41,10 @@ import javax.net.ssl.SSLSocket;
  * methods added by X509HostnameVerifier.
  *
  * @since 4.0
+ *
+ * @deprecated (4.4) Use {@link javax.net.ssl.HostnameVerifier}.
  */
+@Deprecated
 public interface X509HostnameVerifier extends HostnameVerifier {
 
     /**

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java
Fri Aug  8 14:00:55 2014
@@ -38,6 +38,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
+import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
 
@@ -158,7 +159,7 @@ import org.apache.http.util.VersionInfo;
 public class HttpClientBuilder {
 
     private HttpRequestExecutor requestExec;
-    private X509HostnameVerifier hostnameVerifier;
+    private HostnameVerifier hostnameVerifier;
     private LayeredConnectionSocketFactory sslSocketFactory;
     private SSLContext sslcontext;
     private HttpClientConnectionManager connManager;
@@ -232,13 +233,30 @@ public class HttpClientBuilder {
      * Please note this value can be overridden by the {@link #setConnectionManager(
      *   org.apache.http.conn.HttpClientConnectionManager)} and the {@link #setSSLSocketFactory(
      *   org.apache.http.conn.socket.LayeredConnectionSocketFactory)} methods.
+     *
+     *   @deprecated (4.4)
      */
+    @Deprecated
     public final HttpClientBuilder setHostnameVerifier(final X509HostnameVerifier hostnameVerifier)
{
         this.hostnameVerifier = hostnameVerifier;
         return this;
     }
 
     /**
+     * Assigns {@link javax.net.ssl.HostnameVerifier} instance.
+     * <p/>
+     * Please note this value can be overridden by the {@link #setConnectionManager(
+     *   org.apache.http.conn.HttpClientConnectionManager)} and the {@link #setSSLSocketFactory(
+     *   org.apache.http.conn.socket.LayeredConnectionSocketFactory)} methods.
+     *
+     *   @since 4.4
+     */
+    public final HttpClientBuilder setSSLHostnameVerifier(final HostnameVerifier hostnameVerifier)
{
+        this.hostnameVerifier = hostnameVerifier;
+        return this;
+    }
+
+    /**
      * Assigns {@link SSLContext} instance.
      * <p/>
      * <p/>
@@ -780,9 +798,9 @@ public class HttpClientBuilder {
                         System.getProperty("https.protocols")) : null;
                 final String[] supportedCipherSuites = systemProperties ? split(
                         System.getProperty("https.cipherSuites")) : null;
-                X509HostnameVerifier hostnameVerifierCopy = this.hostnameVerifier;
+                HostnameVerifier hostnameVerifierCopy = this.hostnameVerifier;
                 if (hostnameVerifierCopy == null) {
-                    hostnameVerifierCopy = SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
+                    hostnameVerifierCopy = SSLConnectionSocketFactory.getDefaultHostnameVerifier();
                 }
                 if (sslcontext != null) {
                     sslSocketFactoryCopy = new SSLConnectionSocketFactory(

Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java?rev=1616758&r1=1616757&r2=1616758&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java
Fri Aug  8 14:00:55 2014
@@ -35,8 +35,8 @@ import java.security.cert.X509Certificat
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
+import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
@@ -67,26 +67,14 @@ public class TestSSLSocketFactory {
         }
     }
 
-    static class TestX509HostnameVerifier implements X509HostnameVerifier {
+    static class TestX509HostnameVerifier implements HostnameVerifier {
 
         private boolean fired = false;
 
         @Override
         public boolean verify(final String host, final SSLSession session) {
-            return true;
-        }
-
-        @Override
-        public void verify(final String host, final SSLSocket ssl) throws IOException {
             this.fired = true;
-        }
-
-        @Override
-        public void verify(final String host, final String[] cns, final String[] subjectAlts)
throws SSLException {
-        }
-
-        @Override
-        public void verify(final String host, final X509Certificate cert) throws SSLException
{
+            return true;
         }
 
         public boolean isFired() {
@@ -227,7 +215,7 @@ public class TestSSLSocketFactory {
         final SSLContext defaultsslcontext = SSLContexts.createDefault();
 
         final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(defaultsslcontext,
-                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+                NoopHostnameVerifier.INSTANCE);
 
         final Socket socket = socketFactory.createSocket(context);
         final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort());
@@ -260,7 +248,7 @@ public class TestSSLSocketFactory {
             .build();
         final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                 sslcontext,
-                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+                NoopHostnameVerifier.INSTANCE);
 
         final Socket socket = socketFactory.createSocket(context);
         final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort());
@@ -269,12 +257,4 @@ public class TestSSLSocketFactory {
         sslSocket.close();
     }
 
-    @Test
-    public void testDefaultHostnameVerifier() throws Exception {
-        final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
-                SSLContexts.createDefault(),
-                null);
-        Assert.assertNotNull(socketFactory.getHostnameVerifier());
-    }
-
 }



Mime
View raw message