mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
21.01.2009 55803de4603dc853f1d00525c10b99e4557a7abc
Fix for issue 3724 (ApplicationTrustManager.java use hard coded provider and algorithm)

The new proposed fix consists on allowing the user to specify the provider and algorithm to be used by the application trust manager. If nothing is specified, the code will try to use the SunJSEE provider and SunX509 algorithm (the behavior before the fix). If the provider is not available, the code will try to use only the SunX509 algorithm. If this also fails, the code will fallback and use the default algorithm of the JVM.

The previous fix generated problems for instance on Mac OS where the default algorithm is PKIX: in this case it is required to specify (using for instance java properties) the location of the trustmanager.

With the new fix, the user will be able to specify any provider or algorithm to be used, but the default behavior will be to use SunJSEE and SunX509 which works fine in most platforms.


2 files modified
199 ■■■■ changed files
opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java 113 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java 86 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java
@@ -31,6 +31,7 @@
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
@@ -40,6 +41,7 @@
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
@@ -73,44 +75,89 @@
  public ApplicationKeyManager(KeyStore keystore, char[] password)
  {
    KeyManagerFactory kmf = null;
    try
    {
      String algo = KeyManagerFactory.getDefaultAlgorithm();
      kmf = KeyManagerFactory.getInstance(algo);
      kmf.init(keystore, password);
      KeyManager kms[] = kmf.getKeyManagers();
    String userSpecifiedAlgo =
      System.getProperty("org.opends.admin.keymanageralgo");
    String userSpecifiedProvider =
      System.getProperty("org.opends.admin.keymanagerprovider");
    LOG.log(Level.INFO, "User specified algo: "+userSpecifiedAlgo);
    LOG.log(Level.INFO, "User specified provider: "+userSpecifiedProvider);
      /*
       * Iterate over the returned keymanagers, look for an instance
       * of X509KeyManager. If found, use that as our "default" key
       * manager.
       */
      for (int i = 0; i < kms.length; i++)
    // Have some fallbacks to choose the provider and algorith of the key
    // manager.  First see if the user wanted to use something specific,
    // then try with the SunJSSE provider and SunX509 algorithm. Finally,
    // fallback to the default algorithm of the JVM.
    String[] preferredProvider =
    {
        userSpecifiedProvider,
        "SunJSSE",
        null,
        null
    };
    String[] preferredAlgo =
    {
        userSpecifiedAlgo,
        "SunX509",
        "SunX509",
        TrustManagerFactory.getDefaultAlgorithm()
    };
    for (int i=0; i<preferredProvider.length && keyManager == null; i++)
    {
      String provider = preferredProvider[i];
      String algo = preferredAlgo[i];
      if (algo == null)
      {
        if (kms[i] instanceof X509KeyManager)
        continue;
      }
      try
      {
        if (provider != null)
        {
          keyManager = (X509KeyManager) kms[i];
          break;
          kmf = KeyManagerFactory.getInstance(algo, provider);
        }
        else
        {
          kmf = KeyManagerFactory.getInstance(algo);
        }
        kmf.init(keystore, password);
        KeyManager kms[] = kmf.getKeyManagers();
        /*
         * Iterate over the returned keymanagers, look for an instance
         * of X509KeyManager. If found, use that as our "default" key
         * manager.
         */
        for (int j = 0; j < kms.length; j++)
        {
          if (kms[i] instanceof X509KeyManager)
          {
            keyManager = (X509KeyManager) kms[j];
            break;
          }
        }
      }
    }
    catch (NoSuchAlgorithmException e)
    {
      // Nothing to do. Maybe we should avoid this and be strict, but we are
      // in a best effor mode.
      LOG.log(Level.WARNING, "Error with the algorithm", e);
    }
    catch (KeyStoreException e)
    {
      // Nothing to do. Maybe we should avoid this and be strict, but we are
      // in a best effor mode..
      LOG.log(Level.WARNING, "Error with the keystore", e);
    }
    catch (UnrecoverableKeyException e)
    {
      // Nothing to do. Maybe we should avoid this and be strict, but we are
      // in a best effor mode.
      LOG.log(Level.WARNING, "Error with the key", e);
      catch (NoSuchAlgorithmException e)
      {
        // Nothing to do. Maybe we should avoid this and be strict, but we are
        // in a best effor mode.
        LOG.log(Level.WARNING, "Error with the algorithm", e);
      }
      catch (KeyStoreException e)
      {
        // Nothing to do. Maybe we should avoid this and be strict, but we are
        // in a best effor mode..
        LOG.log(Level.WARNING, "Error with the keystore", e);
      }
      catch (UnrecoverableKeyException e)
      {
        // Nothing to do. Maybe we should avoid this and be strict, but we are
        // in a best effor mode.
        LOG.log(Level.WARNING, "Error with the key", e);
      }
      catch (NoSuchProviderException e)
      {
        // Nothing to do. Maybe we should avoid this and be strict, but we are
        // in a best effor mode.
        LOG.log(Level.WARNING, "Error with the provider", e);
      }
    }
  }
opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java
@@ -30,6 +30,7 @@
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -95,40 +96,79 @@
  /**
   * The default constructor.
   *
   * @param keystore The keystore to use for this trustmanager.
   */
  public ApplicationTrustManager(KeyStore keystore)
  {
    TrustManagerFactory tmf = null;
    this.keystore = keystore;
    try
    String userSpecifiedAlgo =
      System.getProperty("org.opends.admin.trustmanageralgo");
    String userSpecifiedProvider =
      System.getProperty("org.opends.admin.trustmanagerprovider");
    LOG.log(Level.INFO, "User specified algo: "+userSpecifiedAlgo);
    LOG.log(Level.INFO, "User specified provider: "+userSpecifiedProvider);
    // Have some fallbacks to choose the provider and algorith of the key
    // manager.  First see if the user wanted to use something specific,
    // then try with the SunJSSE provider and SunX509 algorithm. Finally,
    // fallback to the default algorithm of the JVM.
    String[] preferredProvider =
    {
      String algo = TrustManagerFactory.getDefaultAlgorithm();
      tmf = TrustManagerFactory.getInstance(algo);
      tmf.init(keystore);
      TrustManager[] trustManagers = tmf.getTrustManagers();
      for (int i=0; i < trustManagers.length; i++)
        userSpecifiedProvider,
        "SunJSSE",
        null,
        null
    };
    String[] preferredAlgo =
    {
        userSpecifiedAlgo,
        "SunX509",
        "SunX509",
        TrustManagerFactory.getDefaultAlgorithm()
    };
    for (int i=0; i<preferredProvider.length && trustManager == null; i++)
    {
      String provider = preferredProvider[i];
      String algo = preferredAlgo[i];
      if (algo == null)
      {
        if (trustManagers[i] instanceof X509TrustManager)
        continue;
      }
      try
      {
        if (provider != null)
        {
          trustManager = (X509TrustManager)trustManagers[i];
          break;
          tmf = TrustManagerFactory.getInstance(algo, provider);
        }
        else
        {
          tmf = TrustManagerFactory.getInstance(algo);
        }
        tmf.init(keystore);
        TrustManager[] trustManagers = tmf.getTrustManagers();
        for (int j=0; j < trustManagers.length; j++)
        {
          if (trustManagers[j] instanceof X509TrustManager)
          {
            trustManager = (X509TrustManager)trustManagers[j];
            break;
          }
        }
      }
    }
    catch (NoSuchAlgorithmException e)
    {
      // Nothing to do: if this occurs we will systematically refuse the
      // certificates.  Maybe we should avoid this and be strict, but we are
      // in a best effor mode.
      LOG.log(Level.WARNING, "Error with the algorithm", e);
    }
    catch (KeyStoreException e)
    {
      // Nothing to do: if this occurs we will systematically refuse the
      // certificates.  Maybe we should avoid this and be strict, but we are
      // in a best effor mode.
      LOG.log(Level.WARNING, "Error with the keystore", e);
      catch (NoSuchProviderException e)
      {
        LOG.log(Level.WARNING, "Error with the provider: "+provider, e);
      }
      catch (NoSuchAlgorithmException e)
      {
        LOG.log(Level.WARNING, "Error with the algorithm: "+algo, e);
      }
      catch (KeyStoreException e)
      {
        LOG.log(Level.WARNING, "Error with the keystore", e);
      }
    }
  }