You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by sebb <se...@gmail.com> on 2014/08/09 14:44:42 UTC

Re: 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/

On 8 August 2014 15:00,  <ol...@apache.org> wrote:
> 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

So is this still needed, given that HC requires 1.5+ now?

> +            // 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

So is this still needed, given that HC requires 1.5+ now?


> +                // 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());
> -    }
> -
>  }
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: svn commit: r1616758

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Sat, 2014-08-09 at 13:44 +0100, sebb wrote:
> On 8 August 2014 15:00,  <ol...@apache.org> wrote:
> > 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

...

> >      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
> 
> So is this still needed, given that HC requires 1.5+ now?
> 

We are even 1.6+ in trunk. I simply do not know whether or not it is
still need. Doing #available on input string is pretty cheap, however.
If it can help in some cases, why not?

> 
> > +                // 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();

Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org