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 52ee80468..b4e52ba09 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,6 +26,16 @@ */ 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; import org.apache.http.conn.scheme.Scheme; @@ -38,6 +48,10 @@ import org.apache.http.conn.ssl.SSLSocketFactory; @ThreadSafe public final class SchemeRegistryFactory { + /** + * Initializes default scheme registry based on JSSE defaults. System properties will + * not be taken into consideration. + */ public static SchemeRegistry createDefault() { SchemeRegistry registry = new SchemeRegistry(); registry.register( @@ -47,5 +61,128 @@ public final class SchemeRegistryFactory { return registry; } + private final static char[] EMPTY_PASSWORD = "".toCharArray(); + + /** + * Initializes default scheme registry using system properties as described in + * + * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform + * Standard Edition 5 + * + * @since 4.2 + */ + public static SchemeRegistry createSystemDefault() throws IOException, GeneralSecurityException { + 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))); + return registry; + } }