HTTPCLIENT-1320: Leverage javax.net.ssl.SSLSocketFactory#getDefault() to initialize SSL context based on system defaults instead of using an internal custom routine
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1454687 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ec85a83173
commit
9d6d3b6288
|
@ -3,15 +3,14 @@ Changes since 4.3 ALPHA1
|
|||
* [HTTPCLIENT-1317] InetAddressUtils should handle IPv6 Addresses with Embedded IPv4 Addresses
|
||||
Contributed Sebastian Bazley <sebb at apache.org>.
|
||||
|
||||
* [HTTPCLIENT-1320] Leverage javax.net.ssl.SSLSocketFactory#getDefault() to initialize SSL context
|
||||
based on system defaults instead of using an internal custom routine.
|
||||
Contributed by Abe Backus <abraham at backus.com> and Oleg Kalnichevski <olegk at apache.org>
|
||||
|
||||
* [HTTPCLIENT-1315] NTLM support did not work properly when the target (as returned
|
||||
in the Type 2 message) differed from the domain as supplied by the user.
|
||||
Contributed by Karl Wright <kwright at apache.org>
|
||||
|
||||
* [HTTPCLIENT-1320] SSLSocketFactory#createSystemSSLContext causes UnrecoverableKeyException
|
||||
'Password verification failed' when a truststore is specified with 'javax.net.ssl.trustStore'
|
||||
system property is used without a password.
|
||||
Contributed by Abe Backus <abraham at backus.com>
|
||||
|
||||
* [HTTPCLIENT-1316] Certificate verification rejects IPv6 addresses which are not String-equal.
|
||||
Contributed Sebastian Bazley <sebb at apache.org>.
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ import org.apache.http.conn.routing.HttpRoute;
|
|||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainSocketFactory;
|
||||
import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLContexts;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.conn.ssl.X509HostnameVerifier;
|
||||
import org.apache.http.impl.DefaultHttpResponseFactory;
|
||||
|
@ -140,7 +141,7 @@ public class ClientConfiguration {
|
|||
|
||||
// SSL context for secure connections can be created either based on
|
||||
// system or application specific properties.
|
||||
SSLContext sslcontext = SSLSocketFactory.createSystemSSLContext();
|
||||
SSLContext sslcontext = SSLContexts.createSystemDefault();
|
||||
// Use custom hostname verifier to customize SSL hostname verification.
|
||||
X509HostnameVerifier hostnameVerifier = new BrowserCompatHostnameVerifier();
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.annotation.Immutable;
|
||||
|
||||
/**
|
||||
* {@link SSLContext} factory methods.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class SSLContexts {
|
||||
|
||||
/**
|
||||
* Creates default factory based on the standard JSSE trust material
|
||||
* (<code>cacerts</code> file in the security properties directory). System properties
|
||||
* are not taken into consideration.
|
||||
*
|
||||
* @return the default SSL socket factory
|
||||
*/
|
||||
public static final SSLContext createDefault() throws SSLInitializationException {
|
||||
try {
|
||||
final SSLContext sslcontext = SSLContext.getInstance("TLS");
|
||||
sslcontext.init(null, null, null);
|
||||
return sslcontext;
|
||||
} catch (final NoSuchAlgorithmException ex) {
|
||||
throw new SSLInitializationException(ex.getMessage(), ex);
|
||||
} catch (final KeyManagementException ex) {
|
||||
throw new SSLInitializationException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates default SSL context based on system properties. This method obtains
|
||||
* default SSL context by calling <code>SSLContext.getInstance("Default")</code>.
|
||||
* Please note that <code>Default</code> algorithm is supported as of Java 6.
|
||||
* This method will fall back onto {@link #createDefault()} when
|
||||
* <code>Default</code> algorithm is not available.
|
||||
*
|
||||
* @return default system SSL context
|
||||
*/
|
||||
public static final SSLContext createSystemDefault() throws SSLInitializationException {
|
||||
try {
|
||||
return SSLContext.getInstance("Default");
|
||||
} catch (final NoSuchAlgorithmException ex) {
|
||||
return createDefault();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
package org.apache.http.conn.ssl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
@ -39,10 +37,8 @@ import java.security.KeyManagementException;
|
|||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
|
@ -158,45 +154,32 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL
|
|||
public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
|
||||
= new StrictHostnameVerifier();
|
||||
|
||||
private final static char[] EMPTY_PASSWORD = "".toCharArray();
|
||||
|
||||
/**
|
||||
* Gets the default factory, which uses the default JSSE settings for initializing
|
||||
* the SSL context.
|
||||
* 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.
|
||||
*
|
||||
* @return the default SSL socket factory
|
||||
* @return default SSL socket factory
|
||||
*/
|
||||
public static SSLSocketFactory getSocketFactory() throws SSLInitializationException {
|
||||
return new SSLSocketFactory(createDefaultSSLContext());
|
||||
return new SSLSocketFactory(
|
||||
SSLContexts.createDefault(),
|
||||
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default factory, which uses system properties for initializing the SSL context
|
||||
* Obtains default SSL socket factory with an SSL context based on system properties
|
||||
* as described in
|
||||
* <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">
|
||||
* "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform
|
||||
* Standard Edition 5</a>
|
||||
* <p>
|
||||
* The following system properties are taken into account by this method:
|
||||
* <ul>
|
||||
* <li>ssl.TrustManagerFactory.algorithm</li>
|
||||
* <li>javax.net.ssl.trustStoreType</li>
|
||||
* <li>javax.net.ssl.trustStore</li>
|
||||
* <li>javax.net.ssl.trustStoreProvider</li>
|
||||
* <li>javax.net.ssl.trustStorePassword</li>
|
||||
* <li>java.home</li>
|
||||
* <li>ssl.KeyManagerFactory.algorithm</li>
|
||||
* <li>javax.net.ssl.keyStoreType</li>
|
||||
* <li>javax.net.ssl.keyStore</li>
|
||||
* <li>javax.net.ssl.keyStoreProvider</li>
|
||||
* <li>javax.net.ssl.keyStorePassword</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
*
|
||||
* @return the system SSL socket factory
|
||||
* @return default system SSL socket factory
|
||||
*/
|
||||
public static SSLSocketFactory getSystemSocketFactory() throws SSLInitializationException {
|
||||
return new SSLSocketFactory(createSystemSSLContext());
|
||||
return new SSLSocketFactory(
|
||||
(javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(),
|
||||
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
|
||||
}
|
||||
|
||||
private final javax.net.ssl.SSLSocketFactory socketfactory;
|
||||
|
@ -238,138 +221,6 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL
|
|||
return sslcontext;
|
||||
}
|
||||
|
||||
private static SSLContext createSystemSSLContext(
|
||||
String algorithm,
|
||||
final SecureRandom random) throws IOException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||
KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException {
|
||||
if (algorithm == null) {
|
||||
algorithm = TLS;
|
||||
}
|
||||
TrustManagerFactory tmfactory = null;
|
||||
|
||||
String trustAlgorithm = System.getProperty("ssl.TrustManagerFactory.algorithm");
|
||||
if (trustAlgorithm == null) {
|
||||
trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
}
|
||||
String trustStoreType = System.getProperty("javax.net.ssl.trustStoreType");
|
||||
if (trustStoreType == null) {
|
||||
trustStoreType = KeyStore.getDefaultType();
|
||||
}
|
||||
if ("none".equalsIgnoreCase(trustStoreType)) {
|
||||
tmfactory = TrustManagerFactory.getInstance(trustAlgorithm);
|
||||
} else {
|
||||
File trustStoreFile = null;
|
||||
final String s = System.getProperty("javax.net.ssl.trustStore");
|
||||
if (s != null) {
|
||||
trustStoreFile = new File(s);
|
||||
tmfactory = TrustManagerFactory.getInstance(trustAlgorithm);
|
||||
final String trustStoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider");
|
||||
KeyStore trustStore;
|
||||
if (trustStoreProvider != null) {
|
||||
trustStore = KeyStore.getInstance(trustStoreType, trustStoreProvider);
|
||||
} else {
|
||||
trustStore = KeyStore.getInstance(trustStoreType);
|
||||
}
|
||||
final String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
|
||||
final FileInputStream instream = new FileInputStream(trustStoreFile);
|
||||
try {
|
||||
trustStore.load(instream, trustStorePassword != null ?
|
||||
trustStorePassword.toCharArray() : null);
|
||||
} finally {
|
||||
instream.close();
|
||||
}
|
||||
tmfactory.init(trustStore);
|
||||
} else {
|
||||
final File javaHome = new File(System.getProperty("java.home"));
|
||||
File file = new File(javaHome, "lib/security/jssecacerts");
|
||||
if (!file.exists()) {
|
||||
file = new File(javaHome, "lib/security/cacerts");
|
||||
trustStoreFile = file;
|
||||
} else {
|
||||
trustStoreFile = file;
|
||||
}
|
||||
tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
final String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
|
||||
final FileInputStream instream = new FileInputStream(trustStoreFile);
|
||||
try {
|
||||
trustStore.load(instream, trustStorePassword != null ? trustStorePassword.toCharArray() : null);
|
||||
} finally {
|
||||
instream.close();
|
||||
}
|
||||
tmfactory.init(trustStore);
|
||||
}
|
||||
}
|
||||
|
||||
KeyManagerFactory kmfactory = null;
|
||||
String keyAlgorithm = System.getProperty("ssl.KeyManagerFactory.algorithm");
|
||||
if (keyAlgorithm == null) {
|
||||
keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
|
||||
}
|
||||
String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
|
||||
if (keyStoreType == null) {
|
||||
keyStoreType = KeyStore.getDefaultType();
|
||||
}
|
||||
if ("none".equalsIgnoreCase(keyStoreType)) {
|
||||
kmfactory = KeyManagerFactory.getInstance(keyAlgorithm);
|
||||
} else {
|
||||
File keyStoreFile = null;
|
||||
final String s = System.getProperty("javax.net.ssl.keyStore");
|
||||
if (s != null) {
|
||||
keyStoreFile = new File(s);
|
||||
}
|
||||
if (keyStoreFile != null) {
|
||||
kmfactory = KeyManagerFactory.getInstance(keyAlgorithm);
|
||||
final String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider");
|
||||
KeyStore keyStore;
|
||||
if (keyStoreProvider != null) {
|
||||
keyStore = KeyStore.getInstance(keyStoreType, keyStoreProvider);
|
||||
} else {
|
||||
keyStore = KeyStore.getInstance(keyStoreType);
|
||||
}
|
||||
final String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
|
||||
final FileInputStream instream = new FileInputStream(keyStoreFile);
|
||||
try {
|
||||
keyStore.load(instream, keyStorePassword != null ?
|
||||
keyStorePassword.toCharArray() : EMPTY_PASSWORD);
|
||||
} finally {
|
||||
instream.close();
|
||||
}
|
||||
kmfactory.init(keyStore, keyStorePassword != null ?
|
||||
keyStorePassword.toCharArray() : EMPTY_PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
final SSLContext sslcontext = SSLContext.getInstance(algorithm);
|
||||
sslcontext.init(
|
||||
kmfactory != null ? kmfactory.getKeyManagers() : null,
|
||||
tmfactory != null ? tmfactory.getTrustManagers() : null,
|
||||
random);
|
||||
return sslcontext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public static SSLContext createDefaultSSLContext() throws SSLInitializationException {
|
||||
try {
|
||||
return createSSLContext(TLS, null, null, null, null, null);
|
||||
} catch (final Exception ex) {
|
||||
throw new SSLInitializationException("Failure initializing default SSL context", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public static SSLContext createSystemSSLContext() throws SSLInitializationException {
|
||||
try {
|
||||
return createSystemSSLContext(TLS, null);
|
||||
} catch (final Exception ex) {
|
||||
throw new SSLInitializationException("Failure initializing default system SSL context", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (4.1) Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore,
|
||||
* SecureRandom, X509HostnameVerifier)}
|
||||
|
|
Loading…
Reference in New Issue