Repository: logging-log4j2
Updated Branches:
  refs/heads/master 8b5d644d5 -> cfc263268


LOG4J2-1896 Update classes in org.apache.logging.log4j.core.net.ssl in APIs 
from String to a PasswordProvider producing char[] for passwords.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/cfc26326
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/cfc26326
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/cfc26326

Branch: refs/heads/master
Commit: cfc263268d46abbae5cf5fdd8e11d30253dd08d2
Parents: 8b5d644
Author: rpopma <[email protected]>
Authored: Sun Sep 24 02:36:35 2017 +0900
Committer: rpopma <[email protected]>
Committed: Sun Sep 24 02:36:35 2017 +0900

----------------------------------------------------------------------
 .../net/ssl/AbstractKeyStoreConfiguration.java  | 33 ++++++++++-----
 .../core/net/ssl/KeyStoreConfiguration.java     | 42 ++++++++++++++-----
 .../core/net/ssl/MemoryPasswordProvider.java    | 36 ++++++++++++++++
 .../log4j/core/net/ssl/PasswordProvider.java    | 41 +++++++++++++++++++
 .../log4j/core/net/ssl/StoreConfiguration.java  | 43 +++++++++++---------
 .../core/net/ssl/TrustStoreConfiguration.java   | 27 ++++++++----
 .../SecureSocketAppenderSocketOptionsTest.java  |  7 ++--
 .../core/net/ssl/KeyStoreConfigurationTest.java | 37 +++++++++++++++--
 .../core/net/ssl/SslConfigurationTest.java      | 37 ++++++++++++-----
 .../core/net/ssl/StoreConfigurationTest.java    | 27 ++++++------
 .../net/ssl/TrustStoreConfigurationTest.java    | 36 ++++++++++++++--
 src/changes/changes.xml                         |  3 ++
 12 files changed, 288 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
index 95d6ec2..5855026 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
@@ -23,6 +23,7 @@ import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
+import java.util.Arrays;
 
 import org.apache.logging.log4j.core.config.ConfigurationSource;
 import org.apache.logging.log4j.core.util.NetUtils;
@@ -34,24 +35,29 @@ public class AbstractKeyStoreConfiguration extends 
StoreConfiguration<KeyStore>
     private final KeyStore keyStore;
     private final String keyStoreType;
 
-    public AbstractKeyStoreConfiguration(final String location, final char[] 
password, final String keyStoreType)
+    public AbstractKeyStoreConfiguration(final String location, final 
PasswordProvider passwordProvider, final String keyStoreType)
             throws StoreConfigurationException {
-        super(location, password);
+        super(location, passwordProvider);
         this.keyStoreType = keyStoreType == null ? 
SslConfigurationDefaults.KEYSTORE_TYPE : keyStoreType;
         this.keyStore = this.load();
     }
 
-    /*
-     * @deprecated Use
-     * 
org.apache.logging.log4j.core.net.ssl.AbstractKeyStoreConfiguration.AbstractKeyStoreConfiguration(String,
 char[],
-     * String)
+    /**
+     * @deprecated Use {@link #AbstractKeyStoreConfiguration(String, 
PasswordProvider, String)} instead
+     */
+    @Deprecated
+    public AbstractKeyStoreConfiguration(final String location, final char[] 
password, final String keyStoreType)
+            throws StoreConfigurationException {
+        this(location, new MemoryPasswordProvider(password), keyStoreType);
+    }
+
+    /**
+     * @deprecated Use {@link #AbstractKeyStoreConfiguration(String, 
PasswordProvider, String)} instead
      */
     @Deprecated
     public AbstractKeyStoreConfiguration(final String location, final String 
password, final String keyStoreType)
             throws StoreConfigurationException {
-        super(location, password);
-        this.keyStoreType = keyStoreType == null ? 
SslConfigurationDefaults.KEYSTORE_TYPE : keyStoreType;
-        this.keyStore = this.load();
+        this(location, new MemoryPasswordProvider(password == null ? null : 
password.toCharArray()), keyStoreType);
     }
 
     @Override
@@ -64,7 +70,14 @@ public class AbstractKeyStoreConfiguration extends 
StoreConfiguration<KeyStore>
             }
             try (final InputStream fin = openInputStream(loadLocation)) {
                 final KeyStore ks = KeyStore.getInstance(this.keyStoreType);
-                ks.load(fin, this.getPasswordAsCharArray());
+                char[] password = this.getPasswordAsCharArray();
+                try {
+                    ks.load(fin, password);
+                } finally {
+                    if (password != null) {
+                        Arrays.fill(password, '\0');
+                    }
+                }
                 LOGGER.debug("KeyStore successfully loaded from location {}", 
loadLocation);
                 return ks;
             }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
index facf153..3fc37bd 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.net.ssl;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
+import java.util.Arrays;
 
 import javax.net.ssl.KeyManagerFactory;
 
@@ -39,9 +40,11 @@ public class KeyStoreConfiguration extends 
AbstractKeyStoreConfiguration {
      *
      * @throws StoreConfigurationException Thrown if this instance cannot load 
the KeyStore.
      */
-    public KeyStoreConfiguration(final String location, final char[] password, 
final String keyStoreType,
-            final String keyManagerFactoryAlgorithm) throws 
StoreConfigurationException {
-        super(location, password, keyStoreType);
+    public KeyStoreConfiguration(final String location,
+                                 final PasswordProvider  passwordProvider,
+                                 final String keyStoreType,
+                                 final String keyManagerFactoryAlgorithm) 
throws StoreConfigurationException {
+        super(location, passwordProvider, keyStoreType);
         this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm == null ? 
KeyManagerFactory.getDefaultAlgorithm()
                 : keyManagerFactoryAlgorithm;
     }
@@ -49,14 +52,25 @@ public class KeyStoreConfiguration extends 
AbstractKeyStoreConfiguration {
     /**
      *
      * @throws StoreConfigurationException Thrown if this instance cannot load 
the KeyStore.
-     * @deprecated Use KeyStoreConfiguration(String, char[], String, String)
+     * @deprecated use {@link #KeyStoreConfiguration(String, PasswordProvider, 
String, String)} instead
+     */
+    public KeyStoreConfiguration(final String location,
+                                 final char[] password,
+                                 final String keyStoreType,
+                                 final String keyManagerFactoryAlgorithm) 
throws StoreConfigurationException {
+        this(location, new MemoryPasswordProvider(password), keyStoreType, 
keyManagerFactoryAlgorithm);
+    }
+
+    /**
+     *
+     * @throws StoreConfigurationException Thrown if this instance cannot load 
the KeyStore.
+     * @deprecated Use {@link #KeyStoreConfiguration(String, PasswordProvider, 
String, String)} instead
      */
     @Deprecated
     public KeyStoreConfiguration(final String location, final String password, 
final String keyStoreType,
             final String keyManagerFactoryAlgorithm) throws 
StoreConfigurationException {
-        super(location, password, keyStoreType);
-        this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm == null ? 
KeyManagerFactory.getDefaultAlgorithm()
-                : keyManagerFactoryAlgorithm;
+        this(location, new MemoryPasswordProvider(password == null ? null : 
password.toCharArray()), keyStoreType,
+                keyManagerFactoryAlgorithm);
     }
 
     /**
@@ -81,7 +95,7 @@ public class KeyStoreConfiguration extends 
AbstractKeyStoreConfiguration {
             @PluginAttribute("type") final String keyStoreType,
             @PluginAttribute("keyManagerFactoryAlgorithm") final String 
keyManagerFactoryAlgorithm) throws StoreConfigurationException {
             // @formatter:on
-        return new KeyStoreConfiguration(location, password, keyStoreType,
+        return new KeyStoreConfiguration(location, new 
MemoryPasswordProvider(password), keyStoreType,
                 keyManagerFactoryAlgorithm);
     }
 
@@ -108,14 +122,22 @@ public class KeyStoreConfiguration extends 
AbstractKeyStoreConfiguration {
             final String keyStoreType,
             final String keyManagerFactoryAlgorithm) throws 
StoreConfigurationException {
             // @formatter:on
-        return new KeyStoreConfiguration(location, password == null ? null : 
password.toCharArray(), keyStoreType,
+        return new KeyStoreConfiguration(location,
+                new MemoryPasswordProvider(password == null ? null : 
password.toCharArray()), keyStoreType,
                 keyManagerFactoryAlgorithm);
     }
 
     public KeyManagerFactory initKeyManagerFactory() throws 
NoSuchAlgorithmException, UnrecoverableKeyException,
             KeyStoreException {
         final KeyManagerFactory kmFactory = 
KeyManagerFactory.getInstance(this.keyManagerFactoryAlgorithm);
-        kmFactory.init(this.getKeyStore(), this.getPasswordAsCharArray());
+        char[] password = this.getPasswordAsCharArray();
+        try {
+            kmFactory.init(this.getKeyStore(), password);
+        } finally {
+            if (password != null) {
+                Arrays.fill(password, '\0');
+            }
+        }
         return kmFactory;
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/MemoryPasswordProvider.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/MemoryPasswordProvider.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/MemoryPasswordProvider.java
new file mode 100644
index 0000000..a1d2b19
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/MemoryPasswordProvider.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.apache.logging.log4j.core.net.ssl;
+
+/**
+ * Simple (and not very secure) PasswordProvider implementation that keeps the 
password char[] array in memory.
+ */
+public class MemoryPasswordProvider implements PasswordProvider {
+    private final char[] password;
+
+    public MemoryPasswordProvider(final char[] chars) {
+        password = chars;
+    }
+
+    @Override
+    public char[] getPassword() {
+        if (password == null) {
+            return null;
+        }
+        return password.clone();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
new file mode 100644
index 0000000..be7c994
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.apache.logging.log4j.core.net.ssl;
+
+/**
+ * PasswordProvider implementations are able to produce a password from 
somewhere. The source of the password data
+ * is implementation-specific.
+ * <p>The {@link #getPassword()} method may be called multiple times as 
needed, so the
+ * caller does not need to (and <b>should not</b>) keep the password data in 
memory for longer than absolutely
+ * necessary. Users of this class should erase the password array by calling
+ * {@link java.util.Arrays#fill(char[], char)} immediately when authentication 
is complete and the password data
+ * is no longer needed.
+ * </p>
+ */
+public interface PasswordProvider {
+
+    /**
+     * Returns a new char[] array with the password characters.
+     * <p>
+     * It is the responsibility of the caller to erase this data by calling
+     * {@link java.util.Arrays#fill(char[], char)} immediately when 
authentication is complete and the password data
+     * is no longer needed.
+     * </p>
+     * @return a copy of the password
+     */
+    char[] getPassword();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
index 47dea1d..9bdeaf5 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.net.ssl;
 
 import java.util.Arrays;
+import java.util.Objects;
 
 import org.apache.logging.log4j.status.StatusLogger;
 
@@ -27,31 +28,35 @@ public class StoreConfiguration<T> {
     protected static final StatusLogger LOGGER = StatusLogger.getLogger();
 
     private String location;
-    private char[] password; // TODO get and set in some obfuscated or 
encrypted format?
+    private PasswordProvider passwordProvider;
 
-    public StoreConfiguration(final String location, final char[] password) {
+    public StoreConfiguration(final String location, final PasswordProvider 
passwordProvider) {
         this.location = location;
-        this.password = password;
+        this.passwordProvider = Objects.requireNonNull(passwordProvider, 
"passwordProvider");
     }
 
     /**
-     * Clears the secret fields in this object.
+     * @deprecated Use {@link #StoreConfiguration(String, PasswordProvider)}
      */
-    public void clearSecrets() {
-        this.location = null;
-        if (password != null) {
-            Arrays.fill(password, Character.MIN_VALUE);
-            this.password = null;
-        }
+    @Deprecated
+    public StoreConfiguration(final String location, final char[] password) {
+        this(location, new MemoryPasswordProvider(password));
     }
 
     /**
-     * @deprecated Use StoreConfiguration(String, char[])
+     * @deprecated Use {@link #StoreConfiguration(String, PasswordProvider)}
      */
     @Deprecated
     public StoreConfiguration(final String location, final String password) {
-        this.location = location;
-        this.password = password == null ? null : password.toCharArray();
+        this(location, new MemoryPasswordProvider(password == null ? null : 
password.toCharArray()));
+    }
+
+    /**
+     * Clears the secret fields in this object.
+     */
+    public void clearSecrets() {
+        this.location = null;
+        this.passwordProvider = null;
     }
 
     public String getLocation() {
@@ -68,15 +73,15 @@ public class StoreConfiguration<T> {
      */
     @Deprecated
     public String getPassword() {
-        return String.valueOf(this.password);
+        return String.valueOf(this.passwordProvider.getPassword());
     }
 
     public char[] getPasswordAsCharArray() {
-        return this.password;
+        return this.passwordProvider.getPassword();
     }
 
     public void setPassword(final char[] password) {
-        this.password = password;
+        this.passwordProvider = new MemoryPasswordProvider(password);
     }
 
     /**
@@ -85,7 +90,7 @@ public class StoreConfiguration<T> {
      */
     @Deprecated
     public void setPassword(final String password) {
-        this.password = password == null ? null : password.toCharArray();
+        this.passwordProvider = new MemoryPasswordProvider(password == null ? 
null : password.toCharArray());
     }
 
     /**
@@ -100,7 +105,7 @@ public class StoreConfiguration<T> {
         final int prime = 31;
         int result = 1;
         result = prime * result + ((location == null) ? 0 : 
location.hashCode());
-        result = prime * result + Arrays.hashCode(password);
+        result = prime * result + 
Arrays.hashCode(passwordProvider.getPassword());
         return result;
     }
 
@@ -123,7 +128,7 @@ public class StoreConfiguration<T> {
         } else if (!location.equals(other.location)) {
             return false;
         }
-        if (!Arrays.equals(password, other.password)) {
+        if (!Arrays.equals(passwordProvider.getPassword(), 
other.passwordProvider.getPassword())) {
             return false;
         }
         return true;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
index 58c4d11..c472186 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
@@ -34,22 +34,32 @@ public class TrustStoreConfiguration extends 
AbstractKeyStoreConfiguration {
 
     private final String trustManagerFactoryAlgorithm;
 
-    public TrustStoreConfiguration(final String location, final char[] 
password, final String keyStoreType,
-            final String trustManagerFactoryAlgorithm) throws 
StoreConfigurationException {
-        super(location, password, keyStoreType);
+    public TrustStoreConfiguration(final String location,
+                                   final PasswordProvider passwordProvider,
+                                   final String keyStoreType,
+                                   final String trustManagerFactoryAlgorithm) 
throws StoreConfigurationException {
+        super(location, passwordProvider, keyStoreType);
         this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm == 
null ? TrustManagerFactory
                 .getDefaultAlgorithm() : trustManagerFactoryAlgorithm;
     }
 
     /**
-     * @deprecated Use TrustStoreConfiguration(String, char[], String, String)
+     * @deprecated Use {@link #TrustStoreConfiguration(String, 
PasswordProvider, String, String)} instead
+     */
+    @Deprecated
+    public TrustStoreConfiguration(final String location, final char[] 
password, final String keyStoreType,
+            final String trustManagerFactoryAlgorithm) throws 
StoreConfigurationException {
+        this(location, new MemoryPasswordProvider(password), keyStoreType, 
trustManagerFactoryAlgorithm);
+    }
+
+    /**
+     * @deprecated Use {@link #TrustStoreConfiguration(String, 
PasswordProvider, String, String)} instead
      */
     @Deprecated
     public TrustStoreConfiguration(final String location, final String 
password, final String keyStoreType,
             final String trustManagerFactoryAlgorithm) throws 
StoreConfigurationException {
-        super(location, password, keyStoreType);
-        this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm == 
null ? TrustManagerFactory
-                .getDefaultAlgorithm() : trustManagerFactoryAlgorithm;
+        this(location, new MemoryPasswordProvider(password == null ? null : 
password.toCharArray()), keyStoreType,
+                trustManagerFactoryAlgorithm);
     }
 
     /**
@@ -74,7 +84,8 @@ public class TrustStoreConfiguration extends 
AbstractKeyStoreConfiguration {
             @PluginAttribute("type") final String keyStoreType,
             @PluginAttribute("trustManagerFactoryAlgorithm") final String 
trustManagerFactoryAlgorithm) throws StoreConfigurationException {
             // @formatter:on
-        return new TrustStoreConfiguration(location, password, keyStoreType, 
trustManagerFactoryAlgorithm);
+        return new TrustStoreConfiguration(location, new 
MemoryPasswordProvider(password), keyStoreType,
+                trustManagerFactoryAlgorithm);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
index 98e1aa7..ade4c56 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.core.net.Rfc1349TrafficClass;
 import org.apache.logging.log4j.core.net.SocketOptions;
 import org.apache.logging.log4j.core.net.TcpSocketManager;
 import org.apache.logging.log4j.core.net.ssl.KeyStoreConfiguration;
+import org.apache.logging.log4j.core.net.ssl.MemoryPasswordProvider;
 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
 import org.apache.logging.log4j.core.net.ssl.StoreConfigurationException;
 import org.apache.logging.log4j.core.net.ssl.TestConstants;
@@ -52,7 +53,7 @@ public class SecureSocketAppenderSocketOptionsTest {
         PORT = AvailablePortFinder.getNextAvailable();
         System.setProperty("SecureSocketAppenderSocketOptionsTest.port", 
Integer.toString(PORT));
         try {
-            initServerSocketFactory();            
+            initServerSocketFactory();
             tcpSocketTestServer = new 
TcpSocketTestServer(serverSocketFactory.createServerSocket(PORT));
             tcpSocketTestServer.start();
             loggerContextRule = new 
LoggerContextRule("log4j-ssl-socket-options.xml");
@@ -74,9 +75,9 @@ public class SecureSocketAppenderSocketOptionsTest {
 
     public static void initServerSocketFactory() throws 
StoreConfigurationException {
         final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
-                TestConstants.KEYSTORE_PWD, null, null);
+                new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), null, 
null);
         final TrustStoreConfiguration tsc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
-                TestConstants.TRUSTSTORE_PWD, null, null);
+                new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), 
null, null);
         sslConfiguration = SslConfiguration.createSSLConfiguration(null, ksc, 
tsc);
         serverSocketFactory = sslConfiguration.getSslServerSocketFactory();
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfigurationTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfigurationTest.java
index ab61e18..ef38483 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfigurationTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfigurationTest.java
@@ -23,14 +23,20 @@ import org.junit.Test;
 
 public class KeyStoreConfigurationTest {
     @Test(expected = StoreConfigurationException.class)
-    public void loadEmptyConfiguration() throws StoreConfigurationException {
+    public void loadEmptyConfigurationDeprecated() throws 
StoreConfigurationException {
         final KeyStoreConfiguration ksc = new KeyStoreConfiguration(null, 
TestConstants.NULL_PWD, null, null);
         final KeyStore ks = ksc.getKeyStore();
         Assert.assertTrue(ks == null);
     }
+    @Test(expected = StoreConfigurationException.class)
+    public void loadEmptyConfiguration() throws StoreConfigurationException {
+        final KeyStoreConfiguration ksc = new KeyStoreConfiguration(null, new 
MemoryPasswordProvider(TestConstants.NULL_PWD), null, null);
+        final KeyStore ks = ksc.getKeyStore();
+        Assert.assertTrue(ks == null);
+    }
 
     @Test
-    public void loadNotEmptyConfiguration() throws StoreConfigurationException 
{
+    public void loadNotEmptyConfigurationDeprecated() throws 
StoreConfigurationException {
         final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, TestConstants.KEYSTORE_PWD,
                 TestConstants.KEYSTORE_TYPE, null);
         final KeyStore ks = ksc.getKeyStore();
@@ -38,7 +44,15 @@ public class KeyStoreConfigurationTest {
     }
 
     @Test
-    public void returnTheSameKeyStoreAfterMultipleLoads() throws 
StoreConfigurationException {
+    public void loadNotEmptyConfiguration() throws StoreConfigurationException 
{
+        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, new 
MemoryPasswordProvider(TestConstants.KEYSTORE_PWD),
+                TestConstants.KEYSTORE_TYPE, null);
+        final KeyStore ks = ksc.getKeyStore();
+        Assert.assertTrue(ks != null);
+    }
+
+    @Test
+    public void returnTheSameKeyStoreAfterMultipleLoadsDeprecated() throws 
StoreConfigurationException {
         final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, TestConstants.KEYSTORE_PWD,
                 TestConstants.KEYSTORE_TYPE, null);
         final KeyStore ks = ksc.getKeyStore();
@@ -46,9 +60,24 @@ public class KeyStoreConfigurationTest {
         Assert.assertTrue(ks == ks2);
     }
 
+    @Test
+    public void returnTheSameKeyStoreAfterMultipleLoads() throws 
StoreConfigurationException {
+        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, new 
MemoryPasswordProvider(TestConstants.KEYSTORE_PWD),
+                TestConstants.KEYSTORE_TYPE, null);
+        final KeyStore ks = ksc.getKeyStore();
+        final KeyStore ks2 = ksc.getKeyStore();
+        Assert.assertTrue(ks == ks2);
+    }
+
     @Test(expected = StoreConfigurationException.class)
-    public void wrongPassword() throws StoreConfigurationException {
+    public void wrongPasswordDeprecated() throws StoreConfigurationException {
         final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, "wrongPassword!", null, 
null);
         ksc.getKeyStore();
     }
+
+    @Test(expected = StoreConfigurationException.class)
+    public void wrongPassword() throws StoreConfigurationException {
+        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, new 
MemoryPasswordProvider("wrongPassword!".toCharArray()), null, null);
+        ksc.getKeyStore();
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationTest.java
index 89fef7c..936cc66 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationTest.java
@@ -27,11 +27,11 @@ import org.junit.Assert;
 import org.junit.Test;
 
 public class SslConfigurationTest {
-    
+
     private static final String TLS_TEST_HOST = "login.yahoo.com";
     private static final int TLS_TEST_PORT = 443;
 
-    public static SslConfiguration createTestSslConfigurationResources() 
throws StoreConfigurationException {
+    public static SslConfiguration 
createTestSslConfigurationResourcesDeprecated() throws 
StoreConfigurationException {
         final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE_RESOURCE,
                 TestConstants.KEYSTORE_PWD, TestConstants.KEYSTORE_TYPE, null);
         final TrustStoreConfiguration tsc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE_RESOURCE,
@@ -39,7 +39,15 @@ public class SslConfigurationTest {
         return SslConfiguration.createSSLConfiguration(null, ksc, tsc);
     }
 
-    public static SslConfiguration createTestSslConfigurationFiles() throws 
StoreConfigurationException {
+    public static SslConfiguration createTestSslConfigurationResources() 
throws StoreConfigurationException {
+        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE_RESOURCE,
+                new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), 
TestConstants.KEYSTORE_TYPE, null);
+        final TrustStoreConfiguration tsc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE_RESOURCE,
+                new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), 
null, null);
+        return SslConfiguration.createSSLConfiguration(null, ksc, tsc);
+    }
+
+    public static SslConfiguration createTestSslConfigurationFilesDeprecated() 
throws StoreConfigurationException {
         final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
                 TestConstants.KEYSTORE_PWD, TestConstants.KEYSTORE_TYPE, null);
         final TrustStoreConfiguration tsc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
@@ -47,7 +55,15 @@ public class SslConfigurationTest {
         return SslConfiguration.createSSLConfiguration(null, ksc, tsc);
     }
 
-    @Test 
+    public static SslConfiguration createTestSslConfigurationFiles() throws 
StoreConfigurationException {
+        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
+                new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), 
TestConstants.KEYSTORE_TYPE, null);
+        final TrustStoreConfiguration tsc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
+                new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), 
null, null);
+        return SslConfiguration.createSSLConfiguration(null, ksc, tsc);
+    }
+
+    @Test
     public void testGettersFromScratchFiles() throws 
StoreConfigurationException {
         Assert.assertNotNull(createTestSslConfigurationFiles().getProtocol());
         
Assert.assertNotNull(createTestSslConfigurationFiles().getKeyStoreConfig());
@@ -55,8 +71,8 @@ public class SslConfigurationTest {
         
Assert.assertNotNull(createTestSslConfigurationFiles().getSslSocketFactory());
         
Assert.assertNotNull(createTestSslConfigurationFiles().getTrustStoreConfig());
     }
-    
-    @Test 
+
+    @Test
     public void testGettersFromScratchResources() throws 
StoreConfigurationException {
         
Assert.assertNotNull(createTestSslConfigurationResources().getProtocol());
         
Assert.assertNotNull(createTestSslConfigurationResources().getKeyStoreConfig());
@@ -64,12 +80,12 @@ public class SslConfigurationTest {
         
Assert.assertNotNull(createTestSslConfigurationResources().getSslSocketFactory());
         
Assert.assertNotNull(createTestSslConfigurationResources().getTrustStoreConfig());
     }
-    
+
     @Test
     public void equals() {
         Assert.assertEquals(SslConfiguration.createSSLConfiguration(null, 
null, null), SslConfiguration.createSSLConfiguration(null, null, null));
     }
-    
+
     @Test
         public void emptyConfigurationDoesntCauseNullSSLSocketFactory() {
         final SslConfiguration sc = 
SslConfiguration.createSSLConfiguration(null, null, null);
@@ -94,7 +110,7 @@ public class SslConfigurationTest {
     @Test
     public void connectionFailsWithoutValidServerCertificate() throws 
IOException, StoreConfigurationException {
         final TrustStoreConfiguration tsc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
-                TestConstants.NULL_PWD, null, null);
+                new MemoryPasswordProvider(TestConstants.NULL_PWD), null, 
null);
         final SslConfiguration sc = 
SslConfiguration.createSSLConfiguration(null, null, tsc);
         final SSLSocketFactory factory = sc.getSslSocketFactory();
         try {
@@ -113,7 +129,8 @@ public class SslConfigurationTest {
 
     @Test
     public void loadKeyStoreWithoutPassword() throws 
StoreConfigurationException {
-        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, TestConstants.NULL_PWD, 
null, null);
+        final KeyStoreConfiguration ksc = new 
KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
+                new MemoryPasswordProvider(TestConstants.NULL_PWD), null, 
null);
         final SslConfiguration sslConf = 
SslConfiguration.createSSLConfiguration(null, ksc, null);
         final SSLSocketFactory factory = sslConf.getSslSocketFactory();
         Assert.assertNotNull(factory);

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/StoreConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/StoreConfigurationTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/StoreConfigurationTest.java
index 65c50bc..2224ab6 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/StoreConfigurationTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/StoreConfigurationTest.java
@@ -16,41 +16,42 @@
  */
 package org.apache.logging.log4j.core.net.ssl;
 
-import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.junit.Assert.*;
+
 @Ignore
 public class StoreConfigurationTest<T extends StoreConfiguration<?>> {
 
     @Test
     public void equalsWithNotNullValues() {
         final String location = "/to/the/file.jks";
-        final char[] password = "changeit".toCharArray();
+        final PasswordProvider password = new 
MemoryPasswordProvider("changeit".toCharArray());
         final StoreConfiguration<Object> a = new 
StoreConfiguration<>(location, password);
         final StoreConfiguration<Object> b = new 
StoreConfiguration<>(location, password);
 
-        Assert.assertTrue(a.equals(b));
-        Assert.assertTrue(b.equals(a));
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
     }
 
     @Test
-    public void equalsWithNullAndNotNullValues() {
+    public void notEqualsWithNullAndNotNullValues() {
         final String location = "/to/the/file.jks";
-        final char[] password = "changeit".toCharArray();
+        final PasswordProvider password = new 
MemoryPasswordProvider("changeit".toCharArray());
         final StoreConfiguration<Object> a = new 
StoreConfiguration<>(location, password);
-        final StoreConfiguration<Object> b = new StoreConfiguration<>(null, 
(char[]) null);
+        final StoreConfiguration<Object> b = new StoreConfiguration<>(null, 
new MemoryPasswordProvider(null));
 
-        Assert.assertTrue(a.equals(b));
-        Assert.assertTrue(b.equals(a));
+        assertNotEquals(a, b);
+        assertNotEquals(b, a);
     }
 
     @Test
     public void equalsWithNullValues() {
-        final StoreConfiguration<Object> a = new StoreConfiguration<>(null, 
(char[]) null);
-        final StoreConfiguration<Object> b = new StoreConfiguration<>(null, 
(char[]) null);
+        final StoreConfiguration<Object> a = new StoreConfiguration<>(null, 
new MemoryPasswordProvider(null));
+        final StoreConfiguration<Object> b = new StoreConfiguration<>(null, 
new MemoryPasswordProvider(null));
 
-        Assert.assertTrue(a.equals(b));
-        Assert.assertTrue(b.equals(a));
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfigurationTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfigurationTest.java
index 8e7a849..14c58bb 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfigurationTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfigurationTest.java
@@ -23,31 +23,59 @@ import org.junit.Test;
 
 public class TrustStoreConfigurationTest {
     @Test(expected = StoreConfigurationException.class)
-    public void loadEmptyConfiguration() throws StoreConfigurationException {
+    public void loadEmptyConfigurationDeprecated() throws 
StoreConfigurationException {
         final TrustStoreConfiguration ksc = new TrustStoreConfiguration(null, 
TestConstants.NULL_PWD, null, null);
         final KeyStore ks = ksc.getKeyStore();
         Assert.assertTrue(ks == null);
     }
+    @Test(expected = StoreConfigurationException.class)
+    public void loadEmptyConfiguration() throws StoreConfigurationException {
+        final TrustStoreConfiguration ksc = new TrustStoreConfiguration(null, 
new MemoryPasswordProvider(TestConstants.NULL_PWD), null, null);
+        final KeyStore ks = ksc.getKeyStore();
+        Assert.assertTrue(ks == null);
+    }
 
     @Test
-    public void loadConfiguration() throws StoreConfigurationException {
+    public void loadConfigurationDeprecated() throws 
StoreConfigurationException {
         final TrustStoreConfiguration ksc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, 
TestConstants.TRUSTSTORE_PWD, null, null);
         final KeyStore ks = ksc.getKeyStore();
         Assert.assertNotNull(ks);
     }
 
     @Test
-    public void returnTheSameKeyStoreAfterMultipleLoads() throws 
StoreConfigurationException {
+    public void loadConfiguration() throws StoreConfigurationException {
+        final TrustStoreConfiguration ksc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, new 
MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), null, null);
+        final KeyStore ks = ksc.getKeyStore();
+        Assert.assertNotNull(ks);
+    }
+
+    @Test
+    public void returnTheSameKeyStoreAfterMultipleLoadsDeprecated() throws 
StoreConfigurationException {
         final TrustStoreConfiguration ksc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, 
TestConstants.TRUSTSTORE_PWD, null, null);
         final KeyStore ks = ksc.getKeyStore();
         final KeyStore ks2 = ksc.getKeyStore();
         Assert.assertTrue(ks == ks2);
     }
 
+    @Test
+    public void returnTheSameKeyStoreAfterMultipleLoads() throws 
StoreConfigurationException {
+        final TrustStoreConfiguration ksc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, new 
MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), null, null);
+        final KeyStore ks = ksc.getKeyStore();
+        final KeyStore ks2 = ksc.getKeyStore();
+        Assert.assertTrue(ks == ks2);
+    }
+
     @Test(expected = StoreConfigurationException.class)
-    public void wrongPassword() throws StoreConfigurationException {
+    public void wrongPasswordDeprecated() throws StoreConfigurationException {
         final TrustStoreConfiguration ksc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, 
"wrongPassword!".toCharArray(), null, null);
         ksc.getKeyStore();
         Assert.assertTrue(false);
     }
+
+    @Test(expected = StoreConfigurationException.class)
+    public void wrongPassword() throws StoreConfigurationException {
+        final TrustStoreConfiguration ksc = new 
TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, new 
MemoryPasswordProvider("wrongPassword!".toCharArray()), null, null);
+        ksc.getKeyStore();
+        Assert.assertTrue(false);
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cfc26326/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 300b443..dff1de7 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
          - "remove" - Removed
     -->
     <release version="2.9.2" date="2017-XX-XX" description="GA Release 2.9.2">
+      <action issue="LOG4J2-1896" dev="rpopma" type="update">
+        Update classes in org.apache.logging.log4j.core.net.ssl in APIs from 
String to a PasswordProvider producing char[] for passwords.
+      </action>
       <action issue="LOG4J2-2031" dev="rpopma" type="fix">
         Until this change, messages appeared out of order in log file any time 
when the async logging queue was full. With this change, messages are only 
logged out of order to prevent deadlock when Log4j2 detects recursive logging 
while the queue is full.
       </action>

Reply via email to