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:
Oleg Kalnichevski 2013-03-09 11:41:56 +00:00
parent ec85a83173
commit 9d6d3b6288
4 changed files with 99 additions and 167 deletions

View File

@ -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>.

View File

@ -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();

View File

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

View File

@ -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)}