You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/05/16 07:25:13 UTC

httpcomponents-core git commit: [HTTPCORE-466] Round out the SslContextBuilder by adding missing APIs. [Forced Update!]

Repository: httpcomponents-core
Updated Branches:
  refs/heads/4.4.x 670a6d5a5 -> 40580bd2d (forced update)


[HTTPCORE-466] Round out the SslContextBuilder by adding missing APIs.


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/40580bd2
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/40580bd2
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/40580bd2

Branch: refs/heads/4.4.x
Commit: 40580bd2d5e998c3726c4285053b33961785956e
Parents: 1adb119
Author: Gary Gregory <ga...@gmail.com>
Authored: Mon May 15 11:01:58 2017 -0700
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Tue May 16 09:23:01 2017 +0200

----------------------------------------------------------------------
 RELEASE_NOTES.txt                               |  3 +
 .../org/apache/http/ssl/SSLContextBuilder.java  | 99 ++++++++++++++++----
 .../apache/http/ssl/TestSSLContextBuilder.java  | 67 ++++++++++++-
 3 files changed, 148 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40580bd2/RELEASE_NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 95d3ac0..94e4c5c 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -24,6 +24,9 @@ Changelog
 * HTTPCORE-465: Update example NHttpReverseProxy to support SSL to origin servers which use self-signed certificates.
   Contributed by Gary Gregory <ggregory at apache.org>
 
+* HTTPCORE-466: Round out the SslContextBuilder by adding missing APIs.
+  Contributed by Gary Gregory <ggregory at apache.org>
+
 
 Release 4.4.6
 -------------------

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40580bd2/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java
----------------------------------------------------------------------
diff --git a/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java b/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java
index f736adb..fc759f1 100644
--- a/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java
+++ b/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java
@@ -71,7 +71,9 @@ import org.apache.http.util.Args;
  * <a href="http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.html#init%28javax.net.ssl.KeyManager[],%20javax.net.ssl.TrustManager[],%20java.security.SecureRandom%29">
  * SSLContext.html#init
  * </a>
- *
+ * <p>
+ * TODO Specify which Oracle JSSE versions the above has been verified.
+ *  </p>
  * @since 4.4
  */
 public class SSLContextBuilder {
@@ -80,7 +82,10 @@ public class SSLContextBuilder {
 
     private String protocol;
     private final Set<KeyManager> keyManagers;
+    private String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
+    private String keyStoreType = KeyStore.getDefaultType();
     private final Set<TrustManager> trustManagers;
+    private String trustManagerFactoryAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
     private SecureRandom secureRandom;
     private Provider provider;
 
@@ -150,11 +155,72 @@ public class SSLContextBuilder {
         return this;
     }
 
+    /**
+     * Sets the key store type.
+     *
+     * @param keyStoreType
+     *            the SSLkey store type. See
+     *            the KeyStore section in the <a href=
+     *            "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore">Java
+     *            Cryptography Architecture Standard Algorithm Name
+     *            Documentation</a> for more information.
+     * @return this builder
+     * @see <a href=
+     *      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore">Java
+     *      Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * @since 4.4.7
+     */
+    public SSLContextBuilder setKeyStoreType(final String keyStoreType) {
+        this.keyStoreType = keyStoreType;
+        return this;
+    }
+
+    /**
+     * Sets the key manager factory algorithm name.
+     *
+     * @param keyManagerFactoryAlgorithm
+     *            the key manager factory algorithm name of the requested protocol. See
+     *            the KeyManagerFactory section in the <a href=
+     *            "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyManagerFactory">Java
+     *            Cryptography Architecture Standard Algorithm Name
+     *            Documentation</a> for more information.
+     * @return this builder
+     * @see <a href=
+     *      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyManagerFactory">Java
+     *      Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * @since 4.4.7
+     */
+    public SSLContextBuilder setKeyManagerFactoryAlgorithm(final String keyManagerFactoryAlgorithm) {
+        this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm;
+        return this;
+    }
+
+    /**
+     * Sets the trust manager factory algorithm name.
+     *
+     * @param trustManagerFactoryAlgorithm
+     *            the trust manager algorithm name of the requested protocol. See
+     *            the TrustManagerFactory section in the <a href=
+     *            "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#TrustManagerFactory">Java
+     *            Cryptography Architecture Standard Algorithm Name
+     *            Documentation</a> for more information.
+     * @return this builder
+     * @see <a href=
+     *      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#TrustManagerFactory">Java
+     *      Cryptography Architecture Standard Algorithm Name Documentation</a>
+     * @since 4.4.7
+     */
+    public SSLContextBuilder setTrustManagerFactoryAlgorithm(final String trustManagerFactoryAlgorithm) {
+        this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm;
+        return this;
+    }
+
     public SSLContextBuilder loadTrustMaterial(
             final KeyStore truststore,
             final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException {
-        final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
-                TrustManagerFactory.getDefaultAlgorithm());
+        final TrustManagerFactory tmfactory = TrustManagerFactory
+                .getInstance(trustManagerFactoryAlgorithm == null ? TrustManagerFactory.getDefaultAlgorithm()
+                        : trustManagerFactoryAlgorithm);
         tmfactory.init(truststore);
         final TrustManager[] tms = tmfactory.getTrustManagers();
         if (tms != null) {
@@ -162,8 +228,7 @@ public class SSLContextBuilder {
                 for (int i = 0; i < tms.length; i++) {
                     final TrustManager tm = tms[i];
                     if (tm instanceof X509TrustManager) {
-                        tms[i] = new TrustManagerDelegate(
-                                (X509TrustManager) tm, trustStrategy);
+                        tms[i] = new TrustManagerDelegate((X509TrustManager) tm, trustStrategy);
                     }
                 }
             }
@@ -184,7 +249,7 @@ public class SSLContextBuilder {
             final char[] storePassword,
             final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
         Args.notNull(file, "Truststore file");
-        final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        final KeyStore trustStore = KeyStore.getInstance(keyStoreType);
         final FileInputStream instream = new FileInputStream(file);
         try {
             trustStore.load(instream, storePassword);
@@ -210,7 +275,7 @@ public class SSLContextBuilder {
             final char[] storePassword,
             final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
         Args.notNull(url, "Truststore URL");
-        final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        final KeyStore trustStore = KeyStore.getInstance(keyStoreType);
         final InputStream instream = url.openStream();
         try {
             trustStore.load(instream, storePassword);
@@ -231,10 +296,11 @@ public class SSLContextBuilder {
             final char[] keyPassword,
             final PrivateKeyStrategy aliasStrategy)
             throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
-        final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
-                KeyManagerFactory.getDefaultAlgorithm());
+        final KeyManagerFactory kmfactory = KeyManagerFactory
+                .getInstance(keyManagerFactoryAlgorithm == null ? KeyManagerFactory.getDefaultAlgorithm()
+                        : keyManagerFactoryAlgorithm);
         kmfactory.init(keystore, keyPassword);
-        final KeyManager[] kms =  kmfactory.getKeyManagers();
+        final KeyManager[] kms = kmfactory.getKeyManagers();
         if (kms != null) {
             if (aliasStrategy != null) {
                 for (int i = 0; i < kms.length; i++) {
@@ -263,7 +329,7 @@ public class SSLContextBuilder {
             final char[] keyPassword,
             final PrivateKeyStrategy aliasStrategy) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
         Args.notNull(file, "Keystore file");
-        final KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        final KeyStore identityStore = KeyStore.getInstance(keyStoreType);
         final FileInputStream instream = new FileInputStream(file);
         try {
             identityStore.load(instream, storePassword);
@@ -286,7 +352,7 @@ public class SSLContextBuilder {
             final char[] keyPassword,
             final PrivateKeyStrategy aliasStrategy) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
         Args.notNull(url, "Keystore URL");
-        final KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        final KeyStore identityStore = KeyStore.getInstance(keyStoreType);
         final InputStream instream = url.openStream();
         try {
             identityStore.load(instream, storePassword);
@@ -449,13 +515,12 @@ public class SSLContextBuilder {
 
     }
 
-    /**
-     * @since 4.4.7
-     */
     @Override
     public String toString() {
-        return "[provider=" + provider + ", protocol=" + protocol + ", keymanagers=" + keyManagers
-                + ", trustmanagers=" + trustManagers + ", secureRandom=" + secureRandom + "]";
+        return "[provider=" + provider + ", protocol=" + protocol + ", keyStoreType=" + keyStoreType
+                + ", keyManagerFactoryAlgorithm=" + keyManagerFactoryAlgorithm + ", keyManagers=" + keyManagers
+                + ", trustManagerFactoryAlgorithm=" + trustManagerFactoryAlgorithm + ", trustManagers=" + trustManagers
+                + ", secureRandom=" + secureRandom + "]";
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40580bd2/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java
----------------------------------------------------------------------
diff --git a/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java b/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java
index c33ee11..bd92532 100644
--- a/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java
+++ b/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java
@@ -36,6 +36,8 @@ import java.net.Socket;
 import java.net.SocketException;
 import java.net.URL;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.security.Security;
 import java.security.UnrecoverableKeyException;
@@ -52,6 +54,7 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
+import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLPeerUnverifiedException;
@@ -59,6 +62,7 @@ import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
 
 import org.apache.commons.lang3.JavaVersion;
 import org.apache.commons.lang3.SystemUtils;
@@ -71,6 +75,7 @@ import org.junit.Test;
  */
 public class TestSSLContextBuilder {
 
+    private static final String PROVIDER_SUN_JSSE = "SunJSSE";
     private ExecutorService executorService;
 
     @After
@@ -90,13 +95,67 @@ public class TestSSLContextBuilder {
     @Test
     public void testBuildAllNull() throws Exception {
         final SSLContext sslContext = SSLContextBuilder.create()
+                .setKeyStoreType(null)
+                .setKeyManagerFactoryAlgorithm(null)
+                .setTrustManagerFactoryAlgorithm(null)
                 .setProtocol(null)
+                .setProvider((String) null)
                 .setSecureRandom(null)
                 .loadTrustMaterial((KeyStore) null, null)
                 .loadKeyMaterial((KeyStore) null, null, null)
                 .build();
         Assert.assertNotNull(sslContext);
         Assert.assertEquals("TLS", sslContext.getProtocol());
+        Assert.assertEquals(PROVIDER_SUN_JSSE,  sslContext.getProvider().getName());
+    }
+
+    @Test
+    public void testBuildAllDefaults() throws Exception {
+        final SSLContext sslContext = SSLContextBuilder.create()
+                .setKeyStoreType(KeyStore.getDefaultType())
+                .setKeyManagerFactoryAlgorithm(KeyManagerFactory.getDefaultAlgorithm())
+                .setTrustManagerFactoryAlgorithm(TrustManagerFactory.getDefaultAlgorithm())
+                .setProvider(PROVIDER_SUN_JSSE)
+                .setProtocol("TLS")
+                .setSecureRandom(null)
+                .loadTrustMaterial((KeyStore) null, null)
+                .loadKeyMaterial((KeyStore) null, null, null)
+                .build();
+        Assert.assertNotNull(sslContext);
+        Assert.assertEquals("TLS", sslContext.getProtocol());
+        Assert.assertEquals(PROVIDER_SUN_JSSE,  sslContext.getProvider().getName());
+    }
+
+    @Test(expected=KeyStoreException.class)
+    public void testBuildNoSuchKeyStoreType() throws Exception {
+        final URL resource1 = getClass().getResource("/test-keypasswd.keystore");
+        final String storePassword = "nopassword";
+        final String keyPassword = "password";
+        SSLContextBuilder.create()
+                .setKeyStoreType(" BAD ")
+                .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
+                .build();
+    }
+
+    @Test(expected=NoSuchAlgorithmException.class)
+    public void testBuildNoSuchKeyManagerFactoryAlgorithm() throws Exception {
+        final URL resource1 = getClass().getResource("/test-keypasswd.keystore");
+        final String storePassword = "nopassword";
+        final String keyPassword = "password";
+        SSLContextBuilder.create()
+                .setKeyManagerFactoryAlgorithm(" BAD ")
+                .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
+                .build();
+    }
+
+    @Test(expected=NoSuchAlgorithmException.class)
+    public void testBuildNoSuchTrustManagerFactoryAlgorithm() throws Exception {
+        final URL resource1 = getClass().getResource("/test-keypasswd.keystore");
+        final String storePassword = "nopassword";
+        SSLContextBuilder.create()
+                .setTrustManagerFactoryAlgorithm(" BAD ")
+                .loadTrustMaterial(resource1, storePassword.toCharArray())
+                .build();
     }
 
     @Test
@@ -637,10 +696,10 @@ public class TestSSLContextBuilder {
         final String storePassword = "nopassword";
         final String keyPassword = "nopassword";
         final SSLContext sslContext=SSLContextBuilder.create()
-                .setProvider(Security.getProvider("SunJSSE"))
+                .setProvider(Security.getProvider(PROVIDER_SUN_JSSE))
                 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
                 .build();
-        Assert.assertTrue(sslContext.getProvider().getName().equals("SunJSSE"));
+        Assert.assertEquals(PROVIDER_SUN_JSSE,  sslContext.getProvider().getName());
     }
 
     @Test
@@ -649,10 +708,10 @@ public class TestSSLContextBuilder {
         final String storePassword = "nopassword";
         final String keyPassword = "nopassword";
         final SSLContext sslContext=SSLContextBuilder.create()
-                .setProvider("SunJSSE")
+                .setProvider(PROVIDER_SUN_JSSE)
                 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
                 .build();
-        Assert.assertTrue(sslContext.getProvider().getName().equals("SunJSSE"));
+        Assert.assertEquals(PROVIDER_SUN_JSSE,  sslContext.getProvider().getName());
     }
 
 }