diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 38ae88a33..5a3271e47 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,6 +1,10 @@ Changes since release 4.3 BETA1 ------------------- +* [HTTPCLIENT-1349] SSLSocketFactory incorrectly identifies key passed with keystore as + the keystore password. + Contributed by David Graff + * [HTTPCLIENT-1346] Ensure propagation of SSL handshake exceptions. Contributed by Pasi Eronen diff --git a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.java b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.java index cf2e3ef27..59f89569a 100644 --- a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.java +++ b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.java @@ -113,11 +113,11 @@ public class SSLContextBuilder { public SSLContextBuilder loadKeyMaterial( final KeyStore keystore, - final char[] keystorePassword) + final char[] keyPassword) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm()); - kmfactory.init(keystore, keystorePassword); + kmfactory.init(keystore, keyPassword); this.keymanagers = kmfactory.getKeyManagers(); return this; } 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 6edf04eb5..612a35046 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 @@ -158,14 +158,14 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL public SSLSocketFactory( final String algorithm, final KeyStore keystore, - final String keystorePassword, + final String keyPassword, final KeyStore truststore, final SecureRandom random, final HostNameResolver nameResolver) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .useProtocol(algorithm) - .loadKeyMaterial(keystore, keystorePassword != null ? keystorePassword.toCharArray() : null) + .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(truststore) .build(), nameResolver); @@ -181,7 +181,7 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL public SSLSocketFactory( final String algorithm, final KeyStore keystore, - final String keystorePassword, + final String keyPassword, final KeyStore truststore, final SecureRandom random, final TrustStrategy trustStrategy, @@ -189,7 +189,7 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .useProtocol(algorithm) - .loadKeyMaterial(keystore, keystorePassword != null ? keystorePassword.toCharArray() : null) + .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(truststore, trustStrategy) .build(), hostnameVerifier); @@ -205,14 +205,14 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL public SSLSocketFactory( final String algorithm, final KeyStore keystore, - final String keystorePassword, + final String keyPassword, final KeyStore truststore, final SecureRandom random, final X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .useProtocol(algorithm) - .loadKeyMaterial(keystore, keystorePassword != null ? keystorePassword.toCharArray() : null) + .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(truststore) .build(), hostnameVerifier); diff --git a/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java b/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java index 4bb759738..c2d52bcee 100644 --- a/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java +++ b/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java @@ -32,6 +32,7 @@ import java.net.InetSocketAddress; import java.net.URL; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -195,4 +196,29 @@ public class TestSSLSocketFactory extends LocalServerTestBase { socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); } + @Test + public void testKeyWithAlternatePassword() throws Exception { + String keystorePassword = "nopassword"; + String keyPassword = "password"; + + ClassLoader cl = getClass().getClassLoader(); + URL url = cl.getResource("test-keypasswd.keystore"); + KeyStore keystore = KeyStore.getInstance("jks"); + keystore.load(url.openStream(), keystorePassword.toCharArray()); + + new SSLSocketFactory(keystore, keyPassword, keystore); + } + + @Test(expected=UnrecoverableKeyException.class) + public void testKeyWithAlternatePasswordInvalid() throws Exception { + String keystorePassword = "nopassword"; + String keyPassword = "!password"; + + ClassLoader cl = getClass().getClassLoader(); + URL url = cl.getResource("test-keypasswd.keystore"); + KeyStore keystore = KeyStore.getInstance("jks"); + keystore.load(url.openStream(), keystorePassword.toCharArray()); + + new SSLSocketFactory(keystore, keyPassword, keystore); + } } diff --git a/httpclient/src/test/resources/test-keypasswd.keystore b/httpclient/src/test/resources/test-keypasswd.keystore new file mode 100644 index 000000000..01dd1bbee Binary files /dev/null and b/httpclient/src/test/resources/test-keypasswd.keystore differ