gt:                 passphrase = WSKeyStore.decodePassword(password).toCharArray();
context: /*******************************************************************************
   * Copyright (c) 2005, 2019, 2020 IBM Corporation and others.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     IBM Corporation - initial API and implementation
   *******************************************************************************/
  
  package com.ibm.ws.ssl.config;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLConnection;
  import java.security.AccessController;
  import java.security.KeyStore;
  import java.security.MessageDigest;
  import java.security.PrivilegedAction;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  import java.security.Security;
  import java.security.cert.X509Certificate;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.Set;
  
  import com.ibm.websphere.ras.Tr;
  import com.ibm.websphere.ras.TraceComponent;
  import com.ibm.websphere.ssl.Constants;
  import com.ibm.websphere.ssl.SSLConfig;
  import com.ibm.websphere.ssl.SSLException;
  import com.ibm.ws.ffdc.FFDCFilter;
  import com.ibm.ws.ssl.core.WSPKCSInKeyStore;
  import com.ibm.ws.ssl.core.WSPKCSInKeyStoreList;
  
  /**
   * KeyStore configuration manager
   * <p>
   * This class handles the configuring, loading/reloading, verifying, etc. of
   * KeyStore objects in the runtime.
   * </p>
   *
   * @author IBM Corporation
   * @version WAS 7.0
   * @since WAS 7.0
   */
  public class KeyStoreManager {
      protected static final TraceComponent tc = Tr.register(KeyStoreManager.class, "SSL", "com.ibm.ws.ssl.resources.ssl");
  
      private static class Singleton {
          static final KeyStoreManager INSTANCE = new KeyStoreManager();
      }
  
      private final Map<String, WSKeyStore> keyStoreMap = new HashMap<String, WSKeyStore>();
      private static WSPKCSInKeyStoreList pkcsStoreList = new WSPKCSInKeyStoreList();
  
      /** HEX character list */
      private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  
      /**
       * Do nothing constructor, used to enforce singleton model.
       */
      private KeyStoreManager() {}
  
      /**
       * Access the singleton instance of the key store manager.
       *
       * @return KeyStoreManager
       */
      public static KeyStoreManager getInstance() {
          return Singleton.INSTANCE;
      }
  
      /**
       * Load the provided list of keystores from the configuration.
       *
       * @param config
       */
      public void loadKeyStores(Map<String, WSKeyStore> config) {
          // now process each keystore in the provided config
          for (Entry<String, WSKeyStore> current : config.entrySet()) {
              try {
                  String name = current.getKey();
                  WSKeyStore keystore = current.getValue();
                  addKeyStoreToMap(name, keystore);
              } catch (Exception e) {
                  FFDCFilter.processException(e, getClass().getName(), "loadKeyStores", new Object[] { this, config });
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                      Tr.event(tc, "Error loading keystore; " + current.getKey() + " " + e);
                  }
              }
          }
      }
  
      /***
       * Adds the keyStore to the keyStoreMap.
       *
       * @param keyStoreName
       * @param ks
       * @throws Exception
       ***/
      public void addKeyStoreToMap(String keyStoreName, WSKeyStore ks) throws Exception {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.entry(tc, "addKeyStoreToMap", "name=" + keyStoreName + ", ks=" + ks);
  
          if (keyStoreMap.containsKey(keyStoreName))
              keyStoreMap.remove(keyStoreName);
          keyStoreMap.put(keyStoreName, ks);
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.exit(tc, "addKeyStoreToMap");
      }
  
      /***
       * Iterates through trusted certificate entries to ensure the signer does not
       * already exist.
       *
       * @param signer
       * @param trustStore
       * @return boolean
       ***/
      public boolean checkIfSignerAlreadyExistsInTrustStore(X509Certificate signer, KeyStore trustStore) {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.entry(tc, "checkIfSignerAlreadyExistsInTrustStore");
  
          try {
              String signerMD5Digest = generateDigest("MD5", signer);
              if (signerMD5Digest == null) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      Tr.exit(tc, "checkIfSignerAlreadyExistsInTrustStore -> false (could not generate digest)");
                  return false;
              }
  
              Enumeration<String> aliases = trustStore.aliases();
  
              while (aliases.hasMoreElements()) {
                  String alias = aliases.nextElement();
  
                  if (trustStore.containsAlias(alias)) {
                      X509Certificate cert = (X509Certificate) trustStore.getCertificate(alias);
  
                      String certMD5Digest = generateDigest("MD5", cert);
  
                      if (signerMD5Digest.equals(certMD5Digest)) {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                              Tr.exit(tc, "checkIfSignerAlreadyExistsInTrustStore -> true (digest matches)");
                          return true;
                      }
                  }
              }
          } catch (Exception e) {
              FFDCFilter.processException(e, getClass().getName(), "checkIfSignerAlreadyExistsInTrustStore", this);
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                  Tr.debug(tc, "Exception checking if signer already exists; " + e);
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.exit(tc, "checkIfSignerAlreadyExistsInTrustStore -> false (no digest matches)");
          return false;
      }
  
      /***
       * Returns the WSKeyStore object given the keyStoreName.
       *
       * @param keyStoreName
       * @return WSKeyStore
       ***/
      public WSKeyStore getKeyStore(String keyStoreName) {
          WSKeyStore ks = keyStoreMap.get(keyStoreName);
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
              if (ks != null) {
                  Tr.debug(tc, "Returning a keyStore for name: " + keyStoreName);
              } else {
                  Tr.debug(tc, "Cannot find a keyStore for name: " + keyStoreName);
              }
          }
  
          return ks;
      }
  
      /***
       * Returns a String[] of all WSKeyStore aliases for this process.
       *
       * @return String[]
       ***/
      public String[] getKeyStoreAliases() {
          Set<String> set = keyStoreMap.keySet();
          return set.toArray(new String[set.size()]);
      }
  
      /**
       * @return total number of unique keystore entries in map. (Filter out duplicates representing same keystore).
       */
      public int getKeyStoreCount() {
          // each keystore usually has two entries in map, it's name and it's service reference name.
          // traverse the map to find the unique ones based on name, and return the count of that.
          HashSet uniqueIds = new HashSet();
          Iterator<Entry<String, WSKeyStore>> it = keyStoreMap.entrySet().iterator();
          while (it.hasNext()) {
              uniqueIds.add(it.next().getValue().getName());
          }
          return uniqueIds.size();
      }
  
      /**
       * Fetch the keystore based on the input parameters.
       *
       * @param name
       * @param type
       *            the type of keystore
       * @param provider
       *            provider associated with the key store
       * @param fileName
       *            location of the key store file
       * @param password
       *            used to access the key store
       * @param create
       * @param sslConfig
       * @return resulting key store
       * @throws Exception
       */
      public KeyStore getKeyStore(String name, String type, String provider, String fileName, String password, boolean create, SSLConfig sslConfig) throws Exception {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.entry(tc, "getKeyStore", new Object[] { name, type, provider, fileName, Boolean.valueOf(create), SSLConfigManager.mask(password) });
  
          if (name != null && !create) {
              WSKeyStore keystore = keyStoreMap.get(name);
  
              if (keystore != null) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      Tr.exit(tc, "getKeyStore (from WSKeyStore)");
                  return keystore.getKeyStore(false, false);
              }
          }
  
          KeyStore keyStore = null;
          InputStream inputStream = null;
          boolean not_finished = true;
          int retry_count = 0;
          boolean fileBased = true;
          List<String> keyStoreTypes = new ArrayList<String>();
  
          // Loop until flag indicates a key store was found or failure occured.
          while (not_finished) {
              // Get a base instance of the keystore based on the type and or the
              // provider.
              if (Constants.KEYSTORE_TYPE_JCERACFKS.equals(type) || Constants.KEYSTORE_TYPE_JCECCARACFKS.equals(type) || Constants.KEYSTORE_TYPE_JCEHYBRIDRACFKS.equals(type))
                  fileBased = false;
              else
                  fileBased = true;
  
              // Get a base instance of the keystore based on the type and or the
              // provider.
              char[] passphrase = null;
              keyStore = KeyStore.getInstance(type);
              // Convert the key store password into a char array.
              if (password != null) {
  