From 420fc2604f026a8b464d97b987b158a9d32fc0c8 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Mon, 10 Oct 2011 14:27:45 +0000 Subject: [PATCH] HTTPCLIENT-1128: added factory method to create SSLSocketFactory instances initialized using system properties git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1180993 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/conn/ssl/SSLSocketFactory.java | 152 +++++++++++++++++- .../http/impl/conn/SchemeRegistryFactory.java | 116 +------------ 2 files changed, 145 insertions(+), 123 deletions(-) diff --git a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java index 903c3fad2..5506583ef 100644 --- a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java +++ b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java @@ -46,6 +46,8 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -56,8 +58,10 @@ 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; /** * Layered socket factory for TLS/SSL connections. @@ -157,14 +161,29 @@ public class SSLSocketFactory implements LayeredSchemeSocketFactory, LayeredSock public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER = new StrictHostnameVerifier(); + private final static char[] EMPTY_PASSWORD = "".toCharArray(); + /** - * Gets the default factory, which uses the default JVM settings for secure - * connections. + * Gets the default factory, which uses the default JSSE settings for initializing + * the SSL context. * - * @return the default factory + * @return the default SSL socket factory */ public static SSLSocketFactory getSocketFactory() { - return new SSLSocketFactory(); + return new SSLSocketFactory(createDefaultSSLContext()); + } + + /** + * Gets the default factory, which uses system properties for initializing the SSL context + * as described in + * + * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform + * Standard Edition 5 + * + * @return the system SSL socket factory + */ + public static SSLSocketFactory getSystemSocketFactory() { + return new SSLSocketFactory(createSystemSSLContext()); } private final javax.net.ssl.SSLSocketFactory socketfactory; @@ -206,6 +225,119 @@ private static SSLContext createSSLContext( 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; + String s = System.getProperty("javax.net.ssl.trustStore"); + if (s != null) { + trustStoreFile = new File(s); + tmfactory = TrustManagerFactory.getInstance(trustAlgorithm); + String trustStoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider"); + KeyStore trustStore; + if (trustStoreProvider != null) { + trustStore = KeyStore.getInstance(trustStoreType, trustStoreProvider); + } else { + trustStore = KeyStore.getInstance(trustStoreType); + } + String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); + FileInputStream instream = new FileInputStream(trustStoreFile); + try { + trustStore.load(instream, trustStorePassword != null ? + trustStorePassword.toCharArray() : EMPTY_PASSWORD); + } finally { + instream.close(); + } + tmfactory.init(trustStore); + } else { + 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()); + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); + if (trustStorePassword == null) { + trustStorePassword = "changeit"; + } + FileInputStream instream = new FileInputStream(trustStoreFile); + try { + trustStore.load(instream, trustStorePassword.toCharArray()); + } 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; + String s = System.getProperty("javax.net.ssl.keyStore"); + if (s != null) { + keyStoreFile = new File(s); + } + if (keyStoreFile != null) { + kmfactory = KeyManagerFactory.getInstance(keyAlgorithm); + String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider"); + KeyStore keyStore; + if (keyStoreProvider != null) { + keyStore = KeyStore.getInstance(keyStoreType, keyStoreProvider); + } else { + keyStore = KeyStore.getInstance(keyStoreType); + } + String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword"); + 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); + } + } + + SSLContext sslcontext = SSLContext.getInstance(algorithm); + sslcontext.init( + kmfactory != null ? kmfactory.getKeyManagers() : null, + tmfactory != null ? tmfactory.getTrustManagers() : null, + random); + return sslcontext; + } + private static SSLContext createDefaultSSLContext() { try { return createSSLContext(TLS, null, null, null, null, null); @@ -214,6 +346,14 @@ private static SSLContext createDefaultSSLContext() { } } + private static SSLContext createSystemSSLContext() { + try { + return createSystemSSLContext(TLS, null); + } catch (Exception ex) { + throw new IllegalStateException("Failure initializing default system SSL context", ex); + } + } + /** * @deprecated Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore, SecureRandom, X509HostnameVerifier)} */ @@ -331,10 +471,6 @@ public SSLSocketFactory( this.nameResolver = null; } - private SSLSocketFactory() { - this(createDefaultSSLContext()); - } - /** * @param params Optional parameters. Parameters passed to this method will have no effect. * This method will create a unconnected instance of {@link Socket} class. diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/SchemeRegistryFactory.java b/httpclient/src/main/java/org/apache/http/impl/conn/SchemeRegistryFactory.java index b4e52ba09..1cada3a1c 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/SchemeRegistryFactory.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/SchemeRegistryFactory.java @@ -26,15 +26,8 @@ */ package org.apache.http.impl.conn; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.security.GeneralSecurityException; -import java.security.KeyStore; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.scheme.PlainSocketFactory; @@ -61,8 +54,6 @@ public static SchemeRegistry createDefault() { return registry; } - private final static char[] EMPTY_PASSWORD = "".toCharArray(); - /** * Initializes default scheme registry using system properties as described in * @@ -75,113 +66,8 @@ public static SchemeRegistry createSystemDefault() throws IOException, GeneralSe SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); - - 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; - String s = System.getProperty("javax.net.ssl.trustStore"); - if (s != null) { - trustStoreFile = new File(s); - tmfactory = TrustManagerFactory.getInstance(trustAlgorithm); - String trustStoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider"); - KeyStore trustStore; - if (trustStoreProvider != null) { - trustStore = KeyStore.getInstance(trustStoreType, trustStoreProvider); - } else { - trustStore = KeyStore.getInstance(trustStoreType); - } - String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); - FileInputStream instream = new FileInputStream(trustStoreFile); - try { - trustStore.load(instream, trustStorePassword != null ? - trustStorePassword.toCharArray() : EMPTY_PASSWORD); - } finally { - instream.close(); - } - tmfactory.init(trustStore); - } else { - 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()); - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); - if (trustStorePassword == null) { - trustStorePassword = "changeit"; - } - FileInputStream instream = new FileInputStream(trustStoreFile); - try { - trustStore.load(instream, trustStorePassword.toCharArray()); - } 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; - String s = System.getProperty("javax.net.ssl.keyStore"); - if (s != null) { - keyStoreFile = new File(s); - } - if (keyStoreFile != null) { - kmfactory = KeyManagerFactory.getInstance(keyAlgorithm); - String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider"); - KeyStore keyStore; - if (keyStoreProvider != null) { - keyStore = KeyStore.getInstance(keyStoreType, keyStoreProvider); - } else { - keyStore = KeyStore.getInstance(keyStoreType); - } - String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword"); - 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); - } - } - - SSLContext sslcontext = SSLContext.getInstance("TLS"); - sslcontext.init( - kmfactory != null ? kmfactory.getKeyManagers() : null, - tmfactory != null ? tmfactory.getTrustManagers() : null, - null); - registry.register( - new Scheme("https", 443, new SSLSocketFactory(sslcontext))); + new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory())); return registry; } }