You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@logging.apache.org by Gary Gregory <ga...@gmail.com> on 2017/09/23 18:10:29 UTC

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

I wonder if this should be called SecretProvider because I am thinking that
optionally (or not) the user name can also be a secret. Also there is such
a thing as other login info like the "realm" in Windows IIRC.

Gary

On Sep 23, 2017 11:36, <rp...@apache.org> wrote:

> 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 <rp...@apache.org>
> Authored: Sun Sep 24 02:36:35 2017 +0900
> Committer: rpopma <rp...@apache.org>
> 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(createTestSslConfigurationFile
> s().getProtocol());
>          Assert.assertNotNull(createTestSslConfigurationFile
> s().getKeyStoreConfig());
> @@ -55,8 +71,8 @@ public class SslConfigurationTest {
>          Assert.assertNotNull(createTestSslConfigurationFile
> s().getSslSocketFactory());
>          Assert.assertNotNull(createTestSslConfigurationFile
> s().getTrustStoreConfig());
>      }
> -
> -    @Test
> +
> +    @Test
>      public void testGettersFromScratchResources() throws
> StoreConfigurationException {
>          Assert.assertNotNull(createTestSslConfigurationReso
> urces().getProtocol());
>          Assert.assertNotNull(createTestSslConfigurationReso
> urces().getKeyStoreConfig());
> @@ -64,12 +80,12 @@ public class SslConfigurationTest {
>          Assert.assertNotNull(createTestSslConfigurationReso
> urces().getSslSocketFactory());
>          Assert.assertNotNull(createTestSslConfigurationReso
> urces().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>
>
>