Deprecated X509HostnameVerifier interface in favor of standard javax.net.ssl.HostnameVerifier
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1616758 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
80b0014754
commit
f5bf414adc
|
@ -60,18 +60,16 @@ import org.apache.http.conn.ManagedHttpClientConnection;
|
|||
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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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.annotation.Immutable;
|
||||
import org.apache.http.util.Args;
|
||||
|
||||
/**
|
||||
* Abstract base class for all standard {@link org.apache.http.conn.ssl.X509HostnameVerifier}
|
||||
* implementations that provides common methods extracting
|
||||
* {@link java.security.cert.X509Certificate} instance to be verified from either
|
||||
* {@link javax.net.ssl.SSLSocket} or {@link javax.net.ssl.SSLSession}.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Immutable
|
||||
public abstract class AbstractBaseHostnameVerifier 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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.Immutable;
|
|||
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.InetAddressUtils;
|
|||
* @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 AbstractCommonHostnameVerifier extends AbstractBaseHostnam
|
|||
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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -35,7 +35,10 @@ import org.apache.http.annotation.Immutable;
|
|||
*
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.4) Use {@link org.apache.http.conn.ssl.NoopHostnameVerifier}
|
||||
*/
|
||||
@Deprecated
|
||||
@Immutable
|
||||
public class AllowAllHostnameVerifier extends AbstractVerifier {
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.conn.ssl;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
|
||||
/**
|
||||
* The NO_OP HostnameVerifier essentially turns hostname verification
|
||||
* off. This implementation is a no-op, and never throws the SSLException.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Immutable
|
||||
public class NoopHostnameVerifier implements HostnameVerifier {
|
||||
|
||||
public static final NoopHostnameVerifier INSTANCE = new NoopHostnameVerifier();
|
||||
|
||||
@Override
|
||||
public boolean verify(final String s, final SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "NO_OP";
|
||||
}
|
||||
|
||||
}
|
|
@ -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.HttpContext;
|
|||
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,15 +130,25 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
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).
|
||||
|
@ -138,9 +157,7 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
* @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 implements LayeredConnectionSocketFactor
|
|||
(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 implements LayeredConnectionSocketFactor
|
|||
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 implements LayeredConnectionSocketFactor
|
|||
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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,12 +233,29 @@ 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/>
|
||||
|
@ -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(
|
||||
|
|
|
@ -35,8 +35,8 @@ import java.security.cert.X509Certificate;
|
|||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue