From 8aa9e3c4288898f16445e768320b6dad1de612e1 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Wed, 25 Mar 2009 21:26:49 +0000
Subject: [PATCH] These changes:

---
 opends/src/server/org/opends/server/util/CertificateManager.java                                 |  873 +++++------------------------
 opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java                              |    9 
 opends/src/server/org/opends/server/util/Platform.java                                           |  683 +++++++++++++++++++++++
 opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java                            |   77 +-
 opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java                                |   10 
 opends/tests/unit-tests-testng/src/server/org/opends/server/util/CertificateManagerTestCase.java |   10 
 opends/src/messages/messages/utility.properties                                                  |   58 ++
 7 files changed, 978 insertions(+), 742 deletions(-)

diff --git a/opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java b/opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java
index d121e66..222c72b 100644
--- a/opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java
+++ b/opends/src/ads/org/opends/admin/ads/util/ApplicationKeyManager.java
@@ -44,6 +44,8 @@
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509KeyManager;
 
+import org.opends.server.util.Platform;
+
 
 /**
  * This class is in charge of checking whether the certificates that are
@@ -80,6 +82,13 @@
     String userSpecifiedProvider =
       System.getProperty("org.opends.admin.keymanagerprovider");
 
+    //Handle IBM specific cases if the user did not specify a algorithm and/or
+    //provider.
+    if(userSpecifiedAlgo == null && Platform.isVendor("IBM"))
+      userSpecifiedAlgo = "IbmX509";
+    if(userSpecifiedProvider == null && Platform.isVendor("IBM"))
+      userSpecifiedProvider = "IBMJSEE2";
+
     // 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,
diff --git a/opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java b/opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java
index a5ea34d..9b8fdee 100644
--- a/opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java
+++ b/opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java
@@ -43,6 +43,8 @@
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
+import org.opends.server.util.Platform;
+
 /**
  * This class is in charge of checking whether the certificates that are
  * presented are trusted or not.
@@ -108,6 +110,13 @@
     String userSpecifiedProvider =
       System.getProperty("org.opends.admin.trustmanagerprovider");
 
+    //Handle IBM specific cases if the user did not specify a algorithm and/or
+    //provider.
+    if(userSpecifiedAlgo == null && Platform.isVendor("IBM"))
+      userSpecifiedAlgo = "IbmX509";
+    if(userSpecifiedProvider == null && Platform.isVendor("IBM"))
+      userSpecifiedProvider = "IBMJSEE2";
+
     // 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,
@@ -126,48 +135,48 @@
         "SunX509",
         TrustManagerFactory.getDefaultAlgorithm()
     };
-    for (int i=0; i<preferredProvider.length && trustManager == null; i++)
-    {
-      String provider = preferredProvider[i];
-      String algo = preferredAlgo[i];
-      if (algo == null)
+      for (int i=0; i<preferredProvider.length && trustManager == null; i++)
       {
-        continue;
-      }
-      try
-      {
-        if (provider != null)
+        String provider = preferredProvider[i];
+        String algo = preferredAlgo[i];
+        if (algo == null)
         {
-          tmf = TrustManagerFactory.getInstance(algo, provider);
+          continue;
         }
-        else
+        try
         {
-          tmf = TrustManagerFactory.getInstance(algo);
-        }
-        tmf.init(keystore);
-        TrustManager[] trustManagers = tmf.getTrustManagers();
-        for (int j=0; j < trustManagers.length; j++)
-        {
-          if (trustManagers[j] instanceof X509TrustManager)
+          if (provider != null)
           {
-            trustManager = (X509TrustManager)trustManagers[j];
-            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 (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);
+        }
       }
-      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);
-      }
-    }
   }
 
   /**
diff --git a/opends/src/messages/messages/utility.properties b/opends/src/messages/messages/utility.properties
index a2cc05b..c55c1d2 100644
--- a/opends/src/messages/messages/utility.properties
+++ b/opends/src/messages/messages/utility.properties
@@ -557,3 +557,61 @@
 INFO_ADMIN_CONN_PROMPT_PORT_NUMBER_270=Directory server administration port number [%d]:
 MILD_ERR_LDIF_INVALID_ATTR_OPTION_271=Unable to parse LDIF entry %s starting \
  at line %d because it has an invalid binary option for attribute %s
+SEVERE_ERR_CERTMGR_INVALID_PKCS11_PATH_272=Invalid key store path for PKCS11 \
+keystore, it must be %s
+SEVERE_ERR_CERTMGR_INVALID_KEYSTORE_PATH_273=Key store path %s exists but is \
+not a file
+SEVERE_ERR_CERTMGR_INVALID_PARENT_274=Parent directory for key store path \
+ %s does not exist or is not a directory
+SEVERE_ERR_CERTMGR_INVALID_STORETYPE_275=Invalid key store type, it must \
+be one of the following: %s, %s, %s or %s
+SEVERE_ERR_CERTMGR_KEYSTORE_NONEXISTANT_276=Keystore does not exist, \
+it must exist to retrieve an alias, delete an alias or generate a \
+certificate request
+SEVERE_ERR_CERTMGR_VALIDITY_277=Validity value %d is invalid, it must \
+be a positive integer
+SEVERE_ERR_CERTMGR_ALIAS_ALREADY_EXISTS_278= A certificate with the alias \
+%s already exists in the key store
+SEVERE_ERR_CERTMGR_ADD_CERT_279=The following error occured when \
+adding a certificate with alias %s to the keystore: %s
+SEVERE_ERR_CERTMGR_ALIAS_INVALID_280=The alias %s is cannot be added to the \
+keystore for one of the following reasons: it already exists in the \
+keystore, or, it is not an instance of a trusted certificate class
+SEVERE_ERR_CERTMGR_CERT_REPLIES_INVALID_281=The alias %s is an instance of \
+a private key entry, which is not supported being added to the keystore \
+at this time
+SEVERE_ERR_CERTMGR_DELETE_ALIAS_282=The following error occured when \
+deleting a certificate with alias %s from the keystore: %s
+SEVERE_ERR_CERTMGR_CERT_REQUEST_283=The following error occured when \
+generating a certificate request with alias %s: %s
+SEVERE_ERR_CERTMGR_GEN_SELF_SIGNED_CERT_284=The following error occured when \
+generating a self-signed certificate using the alias %s: %s
+SEVERE_ERR_CERTMGR_INVALID_CERT_FILE_285=The certificate file %s is \
+invalid because it does not exists, or exists, but is not a file
+SEVERE_ERR_CERTMGR_ALIAS_CAN_NOT_DELETE_286=The alias %s cannot be \
+deleted from the keystore because it does not exist
+SEVERE_ERR_CERTMGR_ALIAS_DOES_NOT_EXIST_287=The alias %s does not exist \
+in the keystore so its key information cannot be retrieved
+SEVERE_ERR_CERTMGR_ALIAS_INVALID_ENTRY_TYPE_288=The alias %s is not a \
+valid keystore entry type, so its key information cannot be retrieved
+SEVERE_ERR_CERTMGR_GET_KEY_289=The key information for alias %s \
+cannot be retrieved because of the following reason: %s
+SEVERE_ERR_CERTMGR_PRIVATE_KEY_290=The private key for alias %s \
+could not be retrieved because it was not a key related entry
+SEVERE_ERR_CERTMGR_ALIAS_NO_CERTIFICATE_291=The alias %s does not \
+does not have a certificate associated with it
+SEVERE_ERR_CERTMGR_TRUSTED_CERT_292=The trusted certificate associated \
+with alias %s could not be added to keystore because of the following \
+reason: %s
+SEVERE_ERR_CERTMGR_FILE_NAME_INVALID_293=The %s is invalid because it is \
+null
+SEVERE_ERR_CERTMGR_VALUE_INVALID_294=The argument %s is invalid because it \
+is either null, or has zero length
+SEVERE_ERR_CERTMGR_CLASS_NOT_FOUND_295=A security class cannot be found \
+in this JVM because of the following reason: %s
+SEVERE_ERR_CERTMGR_SECURITY_296=The security classes could not be \
+initialized because of the following reason: %s
+SEVERE_ERR_CERTMGR_NO_METHOD_297=A method needed in the security classes \
+could not be located because of the following reason: %s
+SEVERE_ERR_CERTMGR_CERT_SIGN_REQ_NOT_SUPPORTED_298=Certificate signing \
+request generation is not supported on JVM supplied by this vendor: %s
diff --git a/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java b/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
index b5351a6..6f8d314 100644
--- a/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
+++ b/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.crypto;
 
@@ -2884,7 +2884,13 @@
     }
 
     final Cipher cipher = getCipher(keyEntry, Cipher.DECRYPT_MODE, iv);
-    return cipher.doFinal(data, readIndex, data.length - readIndex);
+    if(data.length - readIndex > 0)
+          return cipher.doFinal(data, readIndex, data.length - readIndex);
+    else {
+      //IBM Java 6 throws an IllegalArgumentException when there's n
+      // data to process.
+      return cipher.doFinal();
+    }
   }
 
 
diff --git a/opends/src/server/org/opends/server/util/CertificateManager.java b/opends/src/server/org/opends/server/util/CertificateManager.java
index 81b17a3..0647062 100644
--- a/opends/src/server/org/opends/server/util/CertificateManager.java
+++ b/opends/src/server/org/opends/server/util/CertificateManager.java
@@ -24,59 +24,33 @@
  *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
  */
+
 package org.opends.server.util;
 
-
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.OutputStream;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
+import java.io.*;
+import java.security.*;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
-
-import org.opends.server.types.OperatingSystem;
+import org.opends.messages.Message;
+import static org.opends.messages.UtilityMessages.*;
 
 
 /**
  * This class provides an interface for generating self-signed certificates and
  * certificate signing requests, and for importing, exporting, and deleting
- * certificates from a key store.  It supports JKS, JCEKS PKCS11, and PKCS12 key
- * store types.
+ * certificates from a key store.  It supports JKS, PKCS11, and PKCS12 key store
+ * types.
  * <BR><BR>
- * Note that for some operations, particularly those that require updating the
- * contents of a key store (including generating certificates and/or certificate
- * signing  requests, importing certificates, or removing certificates), this
- * class relies on the keytool utility provided with Sun's implementation of the
- * Java runtime  environment.  It will perform the associated operations by
- * invoking the appropriate command.  It is possible that the keytool command
- * will not exist in all Java runtime environments, especially those not created
- * by Sun.  In those cases, it will not be possible to invoke operations that
- * require altering the contents of the key store.  Therefore, it is strongly
- * recommended that any code that may want to make use of this facility should
- * first call {@code mayUseCertificateManager} and if it returns {@code false}
- * the caller should gracefully degrade and suggest that the user perform the
- * operation manually.
+   This code uses the Platform class to perform all of the certificate
+    management.
  */
 @org.opends.server.types.PublicAPI(
      stability=org.opends.server.types.StabilityLevel.VOLATILE,
      mayInstantiate=true,
      mayExtend=false,
      mayInvoke=true)
-public final class CertificateManager
-{
-  /**
-   * The path to the keytool command, which will be required to perform
-   * operations that modify the contents of a key store.
-   */
-  public static final String KEYTOOL_COMMAND;
-
-
+public final class CertificateManager {
 
   /**
    * The key store type value that should be used for the "JKS" key store.
@@ -93,85 +67,43 @@
    */
   public static final String KEY_STORE_TYPE_PKCS11 = "PKCS11";
 
-
-
   /**
    * The key store type value that should be used for the "PKCS12" key store.
    */
   public static final String KEY_STORE_TYPE_PKCS12 = "PKCS12";
 
-
-
   /**
    * The key store path value that must be used in conjunction with the PKCS11
    * key store type.
    */
   public static final String KEY_STORE_PATH_PKCS11 = "NONE";
 
-
-
+  //Error message strings.
+  private static final String KEYSTORE_PATH_MSG = "key store path";
+  private static final String KEYSTORE_TYPE_MSG = "key store type";
+  private static final String KEYSTORE_PWD_MSG = "key store password";
+  private static final String SUBJECT_DN_MSG = "subject DN";
+  private static final String CERT_ALIAS_MSG = "certificate alias";
+  private static final String CERT_REQUEST_FILE_MSG =
+                                                    "certificate request file";
   // The parsed key store backing this certificate manager.
   private KeyStore keyStore;
 
-  // The password that should be used to interact with the key store.
-  private String keyStorePIN;
-
   // The path to the key store that we should be using.
-  private String keyStorePath;
+  private final String keyStorePath;
 
   // The name of the key store type we are using.
-  private String keyStoreType;
+  private final String keyStoreType;
 
-
-
-  static
-  {
-    String keytoolCommand = null;
-
-    try
-    {
-      String cmd = System.getProperty("java.home") + File.separator + "bin" +
-                   File.separator + "keytool";
-      File cmdFile = new File(cmd);
-      if (cmdFile.exists())
-      {
-        keytoolCommand = cmdFile.getAbsolutePath();
-      }
-      else
-      {
-        cmd = cmd + ".exe";
-        cmdFile = new File(cmd);
-        if (cmdFile.exists())
-        {
-          keytoolCommand = cmdFile.getAbsolutePath();
-        }
-        else
-        {
-          keytoolCommand = null;
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      keytoolCommand = null;
-    }
-
-    KEYTOOL_COMMAND = SetupUtils.getScriptPath(keytoolCommand);
-  }
-
-
+  private final char[] password;
 
   /**
-   * Indicates whether it is possible to use this certificate manager code to
-   * perform operations which may alter the contents of a key store.
+   * Always return true.
    *
-   * @return  {@code true} if it appears that the keytool utility is available
-   *          and may be used to execute commands that may alter the contents of
-   *          a key store, or {@code false} if not.
+   * @return  This always returns true;
    */
-  public static boolean mayUseCertificateManager()
-  {
-    return (KEYTOOL_COMMAND != null);
+  public static boolean mayUseCertificateManager() {
+    return true;
   }
 
 
@@ -192,89 +124,49 @@
    *                       {@code KEY_STORE_TYPE_JCEKS},
    *                       {@code KEY_STORE_TYPE_PKCS11}, or
    *                       {@code KEY_STORE_TYPE_PKCS12}.
-   * @param  keyStorePIN   The PIN required to access the key store.  It must
-   *                       not be {@code null}.
+   * @param  keyStorePassword   The password required to access the key store.
+   *                         It must not be {@code null}.
+   * @throws IllegalArgumentException If an argument is invalid or {@code null}.
    *
-   * @throws  IllegalArgumentException  If any of the provided arguments is
-   *                                    invalid.
-   *
-   * @throws  NullPointerException  If any of the provided arguments is
-   *                                {@code null}.
-   *
-   * @throws  UnsupportedOperationException  If it is not possible to use the
-   *                                         certificate manager on the
-   *                                         underlying platform.
    */
   public CertificateManager(String keyStorePath, String keyStoreType,
-                            String keyStorePIN)
-         throws IllegalArgumentException, NullPointerException,
-                UnsupportedOperationException
-  {
-    if ((keyStorePath == null) || (keyStorePath.length() == 0))
-    {
-      throw new NullPointerException("keyStorePath");
-    }
-    else if ((keyStoreType == null) || (keyStoreType.length() == 0))
-    {
-      throw new NullPointerException("keyStoreType");
-    }
-    else if ((keyStorePIN == null) || (keyStorePIN.length() == 0))
-    {
-      throw new NullPointerException("keyStorePIN");
-    }
-
-
-    if (keyStoreType.equals(KEY_STORE_TYPE_PKCS11))
-    {
-      if (! keyStorePath.equals(KEY_STORE_PATH_PKCS11))
-      {
-        // FIXME -- Make this an internationalizeable string.
-        throw new IllegalArgumentException("Invalid key store path for " +
-                                           "PKCS11 keystore -- it must be " +
-                                           KEY_STORE_PATH_PKCS11);
+                            String keyStorePassword)
+  throws IllegalArgumentException {
+    ensureValid(keyStorePath, KEYSTORE_PATH_MSG);
+    ensureValid(keyStoreType, KEYSTORE_TYPE_MSG);
+    ensureValid(keyStorePassword, KEYSTORE_PWD_MSG);
+    if (keyStoreType.equals(KEY_STORE_TYPE_PKCS11)) {
+      if (! keyStorePath.equals(KEY_STORE_PATH_PKCS11)) {
+        Message msg =
+          ERR_CERTMGR_INVALID_PKCS11_PATH.get(KEY_STORE_PATH_PKCS11);
+        throw new IllegalArgumentException(msg.toString());
       }
-    }
-    else if (keyStoreType.equals(KEY_STORE_TYPE_JKS) ||
+    } else if (keyStoreType.equals(KEY_STORE_TYPE_JKS) ||
         keyStoreType.equals(KEY_STORE_TYPE_JCEKS) ||
-             keyStoreType.equals(KEY_STORE_TYPE_PKCS12))
-    {
+        keyStoreType.equals(KEY_STORE_TYPE_PKCS12)) {
       File keyStoreFile = new File(keyStorePath);
-      if (keyStoreFile.exists())
-      {
-        if (! keyStoreFile.isFile())
-        {
-          // FIXME -- Make this an internationalizeable string.
-          throw new IllegalArgumentException("Key store path " + keyStorePath +
-                                             " exists but is not a file.");
+      if (keyStoreFile.exists()) {
+        if (! keyStoreFile.isFile()) {
+          Message msg = ERR_CERTMGR_INVALID_KEYSTORE_PATH.get(keyStorePath);
+          throw new IllegalArgumentException(msg.toString());
         }
-      }
-      else
-      {
-        File keyStoreDirectory = keyStoreFile.getParentFile();
+      } else {
+        final File keyStoreDirectory = keyStoreFile.getParentFile();
         if ((keyStoreDirectory == null) || (! keyStoreDirectory.exists()) ||
-            (! keyStoreDirectory.isDirectory()))
-        {
-          // FIXME -- Make this an internationalizeable string.
-          throw new IllegalArgumentException("Parent directory for key " +
-                         "store path " + keyStorePath + " does not exist or " +
-                         "is not a directory.");
+            (! keyStoreDirectory.isDirectory())) {
+          Message msg = ERR_CERTMGR_INVALID_PARENT.get(keyStorePath);
+          throw new IllegalArgumentException(msg.toString());
         }
       }
+    } else {
+      Message msg =  ERR_CERTMGR_INVALID_STORETYPE.get(
+          KEY_STORE_TYPE_JKS, KEY_STORE_TYPE_JCEKS,
+          KEY_STORE_TYPE_PKCS11, KEY_STORE_TYPE_PKCS12);
+      throw new IllegalArgumentException(msg.toString());
     }
-    else
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new IllegalArgumentException("Invalid key store type -- it must " +
-                  "be one of " + KEY_STORE_TYPE_JKS + ", " +
-                  "be one of " + KEY_STORE_TYPE_JCEKS + ", " +
-                  KEY_STORE_TYPE_PKCS11 + ", or " + KEY_STORE_TYPE_PKCS12);
-    }
-
-
     this.keyStorePath = keyStorePath;
     this.keyStoreType = keyStoreType;
-    this.keyStorePIN  = keyStorePIN;
-
+    this.password  = keyStorePassword.toCharArray();
     keyStore = null;
   }
 
@@ -291,25 +183,13 @@
    *
    * @throws  KeyStoreException  If a problem occurs while attempting to
    *                             interact with the key store.
-   *
-   * @throws  NullPointerException  If the provided alias is {@code null} or a
-   *                                zero-length string.
    */
-  public boolean aliasInUse(String alias)
-         throws KeyStoreException, NullPointerException
-  {
-    if ((alias == null) || (alias.length() == 0))
-    {
-      throw new NullPointerException("alias");
-    }
-
-
+  public boolean aliasInUse(final String alias)
+  throws KeyStoreException {
+    ensureValid(alias, CERT_ALIAS_MSG);
     KeyStore keyStore = getKeyStore();
     if (keyStore == null)
-    {
       return false;
-    }
-
     return keyStore.containsAlias(alias);
   }
 
@@ -324,28 +204,17 @@
    * @throws  KeyStoreException  If a problem occurs while attempting to
    *                             interact with the key store.
    */
-  public String[] getCertificateAliases()
-         throws KeyStoreException
-  {
+  public String[] getCertificateAliases() throws KeyStoreException {
+    Enumeration<String> aliasEnumeration = null;
     KeyStore keyStore = getKeyStore();
     if (keyStore == null)
-    {
       return null;
-    }
-
-    Enumeration<String> aliasEnumeration = keyStore.aliases();
+    aliasEnumeration = keyStore.aliases();
     if (aliasEnumeration == null)
-    {
       return new String[0];
-    }
-
     ArrayList<String> aliasList = new ArrayList<String>();
     while (aliasEnumeration.hasMoreElements())
-    {
       aliasList.add(aliasEnumeration.nextElement());
-    }
-
-
     String[] aliases = new String[aliasList.size()];
     return aliasList.toArray(aliases);
   }
@@ -362,31 +231,22 @@
    *          certificate does not exist.
    *
    * @throws  KeyStoreException  If a problem occurs while interacting with the
-   *                             key store, or the key store does not exist.
-   *
-   * @throws  NullPointerException  If the provided alias is {@code null} or a
-   *                                zero-length string.
+   *                             key store, or the key store does not exist..
    */
-  public Certificate getCertificate(String alias)
-         throws KeyStoreException, NullPointerException
-  {
-    if ((alias == null) || (alias.length() == 0))
-    {
-      throw new NullPointerException("alias");
+  public Certificate  getCertificate(String alias)
+  throws KeyStoreException {
+    ensureValid(alias, CERT_ALIAS_MSG);
+    Certificate cert = null;
+    KeyStore ks = getKeyStore();
+    if (ks == null) {
+      Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get();
+      throw new KeyStoreException(msg.toString());
     }
-
-    KeyStore keyStore = getKeyStore();
-    if (keyStore == null)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new KeyStoreException("The key store does not exist.");
-    }
-
-    return keyStore.getCertificate(alias);
+    cert = ks.getCertificate(alias);
+    return cert;
   }
 
 
-
   /**
    * Generates a self-signed certificate using the provided information.
    *
@@ -398,89 +258,30 @@
    * @param  validity   The length of time in days that the certificate should
    *                    be valid, starting from the time the certificate is
    *                    generated.  It must be a positive integer value.
-   *
-   * @throws  IllegalArgumentException  If the validity is not positive.
-   *
    * @throws  KeyStoreException  If a problem occurs while actually attempting
    *                             to generate the certificate in the key store.
-   *
-   * @throws  NullPointerException  If either the alias or subject DN is null or
-   *                                a zero-length string.
-   *
-   * @throws  UnsupportedOperationException  If it is not possible to use the
-   *                                         keytool utility to alter the
-   *                                         contents of the key store.
+   *@throws IllegalArgumentException If the validity parameter is not a
+   *                                 positive integer, or the alias is already
+   *                                 in the keystore.
    */
   public void generateSelfSignedCertificate(String alias, String subjectDN,
                                             int validity)
-         throws KeyStoreException, IllegalArgumentException,
-                NullPointerException, UnsupportedOperationException
-  {
-    if ((alias == null) || (alias.length() == 0))
-    {
-      throw new NullPointerException("alias");
+  throws KeyStoreException, IllegalArgumentException {
+    ensureValid(alias, CERT_ALIAS_MSG);
+    ensureValid(subjectDN, SUBJECT_DN_MSG);
+    if (validity <= 0) {
+      Message msg = ERR_CERTMGR_VALIDITY.get(validity);
+      throw new IllegalArgumentException(msg.toString());
     }
-    else if ((subjectDN == null) || (subjectDN.length() == 0))
-    {
-      throw new NullPointerException("subjectDN");
+    if (aliasInUse(alias)) {
+      Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias);
+      throw new IllegalArgumentException(msg.toString());
     }
-    else if (validity <= 0)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new IllegalArgumentException("The validity must be positive.");
-    }
-
-    if (KEYTOOL_COMMAND == null)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new UnsupportedOperationException("The certificate manager may " +
-                     "not be used to alter the contents of key stores on " +
-                     "this system.");
-    }
-
-    if (aliasInUse(alias))
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new IllegalArgumentException("A certificate with alias " + alias +
-                                         " already exists in the key store.");
-    }
-
-
-    // Clear the reference to the key store, since it will be altered by
-    // invoking the KeyTool command.
     keyStore = null;
-
-    // First, we need to run with the "-genkey" command to create the private
-    // key.
-    String[] commandElements =
-    {
-      KEYTOOL_COMMAND,
-      getGenKeyCommand(),
-      "-alias", alias,
-      "-dname", subjectDN,
-      "-keyalg", "rsa",
-      "-keystore", keyStorePath,
-      "-storetype", keyStoreType
-    };
-    runKeyTool(commandElements, keyStorePIN, keyStorePIN, true);
-
-    // Next, we need to run with the "-selfcert" command to self-sign the
-    // certificate.
-    commandElements = new String[]
-    {
-      KEYTOOL_COMMAND,
-      "-selfcert",
-      "-alias", alias,
-      "-sigalg", "SHA256withRSA",
-      "-validity", String.valueOf(validity),
-      "-keystore", keyStorePath,
-      "-storetype", keyStoreType
-    };
-    runKeyTool(commandElements, keyStorePIN, keyStorePIN, true);
+    Platform.generateSelfSignedCertificate(getKeyStore(), keyStoreType,
+        keyStorePath, alias, password, subjectDN, validity);
   }
 
-
-
   /**
    * Generates a certificate signing request (CSR) using the provided
    * information.
@@ -497,82 +298,21 @@
    *                             to generate the private key in the key store or
    *                             generate the certificate signing request based
    *                             on that key.
-   *
-   * @throws  IOException  If a problem occurs while attempting to create the
-   *                       file to which the certificate signing request will be
-   *                       written.
-   *
-   * @throws  NullPointerException  If either the alias or subject DN is null or
-   *                                a zero-length string.
-   *
-   * @throws  UnsupportedOperationException  If it is not possible to use the
-   *                                         keytool utility to alter the
-   *                                         contents of the key store.
+   *@throws IllegalArgumentException If the alias already exists in the
+   *                                 keystore.
    */
-  public File generateCertificateSigningRequest(String alias, String subjectDN)
-         throws KeyStoreException, IOException, NullPointerException,
-                UnsupportedOperationException
-  {
-    if ((alias == null) || (alias.length() == 0))
-    {
-      throw new NullPointerException("alias");
+  public File
+  generateCertificateSigningRequest(final String alias, final String subjectDN)
+  throws KeyStoreException, IllegalArgumentException {
+    ensureValid(alias, CERT_ALIAS_MSG);
+    ensureValid(subjectDN, SUBJECT_DN_MSG);
+    if (aliasInUse(alias)) {
+      Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias);
+      throw new IllegalArgumentException(msg.toString());
     }
-    else if ((subjectDN == null) || (subjectDN.length() == 0))
-    {
-      throw new NullPointerException("subjectDN");
-    }
-
-    if (KEYTOOL_COMMAND == null)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new UnsupportedOperationException("The certificate manager may " +
-                     "not be used to alter the contents of key stores on " +
-                     "this system.");
-    }
-
-    if (aliasInUse(alias))
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new IllegalArgumentException("A certificate with alias " + alias +
-                                         " already exists in the key store.");
-    }
-
-
-    // Clear the reference to the key store, since it will be altered by
-    // invoking the KeyTool command.
     keyStore = null;
-
-
-    // First, we need to run with the "-genkey" command to create the private
-    // key.
-    String[] commandElements =
-    {
-      KEYTOOL_COMMAND,
-      getGenKeyCommand(),
-      "-alias", alias,
-      "-dname", subjectDN,
-      "-keyalg", "rsa",
-      "-keystore", keyStorePath,
-      "-storetype", keyStoreType
-    };
-    runKeyTool(commandElements, keyStorePIN, keyStorePIN, true);
-
-    // Next, we need to run with the "-certreq" command to generate the
-    // certificate signing request.
-    File csrFile = File.createTempFile("CertificateManager-", ".csr");
-    csrFile.deleteOnExit();
-    commandElements = new String[]
-    {
-      KEYTOOL_COMMAND,
-      "-certreq",
-      "-alias", alias,
-      "-file", csrFile.getAbsolutePath(),
-      "-keystore", keyStorePath,
-      "-storetype", keyStoreType
-    };
-    runKeyTool(commandElements, keyStorePIN, keyStorePIN, true);
-
-    return csrFile;
+    return Platform.generateCertificateRequest(getKeyStore(), keyStoreType,
+        keyStorePath, alias, password, subjectDN);
   }
 
 
@@ -586,68 +326,25 @@
    *                          be {@code null} or empty.
    * @param  certificateFile  The file containing the encoded certificate.  It
    *                          must not be {@code null}, and the file must exist.
-   *
-   * @throws  IllegalArgumentException  If the provided certificate file does
-   *                                    not exist.
-   *
+
    * @throws  KeyStoreException  If a problem occurs while interacting with the
    *                             key store.
    *
-   * @throws  NullPointerException  If the provided alias is {@code null} or a
-   *                                zero-length string, or the certificate file
-   *                                is {@code null}.
-   *
-   * @throws  UnsupportedOperationException  If it is not possible to use the
-   *                                         keytool utility to alter the
-   *                                         contents of the key store.
+   *@throws IllegalArgumentException If the certificate file is not valid.
    */
   public void addCertificate(String alias, File certificateFile)
-         throws IllegalArgumentException, KeyStoreException,
-                NullPointerException, UnsupportedOperationException
-  {
-    if ((alias == null) || (alias.length() == 0))
-    {
-      throw new NullPointerException("alias");
+  throws  KeyStoreException, IllegalArgumentException {
+    ensureValid(alias, CERT_ALIAS_MSG);
+    ensureFileValid(certificateFile, CERT_REQUEST_FILE_MSG);
+    if ((! certificateFile.exists()) ||
+        (! certificateFile.isFile())) {
+      Message msg = ERR_CERTMGR_INVALID_CERT_FILE.get(
+          certificateFile.getAbsolutePath());
+      throw new IllegalArgumentException(msg.toString());
     }
-
-    if (certificateFile == null)
-    {
-      throw new NullPointerException("certificateFile");
-    }
-    else if ((! certificateFile.exists()) ||
-             (! certificateFile.isFile()))
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new IllegalArgumentException("Certificate file " +
-                                         certificateFile.getAbsolutePath() +
-                                         " does not exist or is not a file.");
-    }
-
-    if (KEYTOOL_COMMAND == null)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new UnsupportedOperationException("The certificate manager may " +
-                     "not be used to alter the contents of key stores on " +
-                     "this system.");
-    }
-
-
-    // Clear the reference to the key store, since it will be altered by
-    // invoking the KeyTool command.
     keyStore = null;
-
-
-    String[] commandElements =
-    {
-      KEYTOOL_COMMAND,
-      "-import",
-      "-noprompt",
-      "-alias", alias,
-      "-file", certificateFile.getAbsolutePath(),
-      "-keystore", keyStorePath,
-      "-storetype", keyStoreType
-    };
-    runKeyTool(commandElements, keyStorePIN, keyStorePIN, true);
+    Platform.addCertificate(getKeyStore(), keyStoreType, keyStorePath, alias,
+        password, certificateFile.getAbsolutePath());
   }
 
 
@@ -658,226 +355,23 @@
    *                be {@code null} or an empty string, and it must exist in
    *                the key store.
    *
-   * @throws  IllegalArgumentException  If the specified certificate does not
-   *                                    exist in the key store.
-   *
    * @throws  KeyStoreException  If a problem occurs while interacting with the
    *                             key store.
-   *
-   * @throws  NullPointerException  If the provided alias is {@code null} or a
-   *                                zero-length string, or the certificate file
-   *                                is {@code null}.
-   *
-   * @throws  UnsupportedOperationException  If it is not possible to use the
-   *                                         keytool utility to alter the
-   *                                         contents of the key store.
+   *@throws IllegalArgumentException If the alias is in use and cannot be
+   *                                 deleted.
    */
   public void removeCertificate(String alias)
-         throws IllegalArgumentException, KeyStoreException,
-                NullPointerException, UnsupportedOperationException
-  {
-    if ((alias == null) || (alias.length() == 0))
-    {
-      throw new NullPointerException("alias");
+  throws KeyStoreException, IllegalArgumentException {
+    ensureValid(alias, CERT_ALIAS_MSG);
+    if (!aliasInUse(alias)) {
+      Message msg = ERR_CERTMGR_ALIAS_CAN_NOT_DELETE.get(alias);
+      throw new IllegalArgumentException(msg.toString());
     }
-
-    if (KEYTOOL_COMMAND == null)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new UnsupportedOperationException("The certificate manager may " +
-                     "not be used to alter the contents of key stores on " +
-                     "this system.");
-    }
-
-    if (! aliasInUse(alias))
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new IllegalArgumentException("There is no certificate with alias " +
-                                         alias + " in the key store.");
-    }
-
-
-    // Clear the reference to the key store, since it will be altered by
-    // invoking the KeyTool command.
     keyStore = null;
-
-
-    String[] commandElements =
-    {
-      KEYTOOL_COMMAND,
-      "-delete",
-      "-alias", alias,
-      "-keystore", keyStorePath,
-      "-storetype", keyStoreType
-    };
-    runKeyTool(commandElements, keyStorePIN, keyStorePIN, true);
+    Platform.deleteAlias(getKeyStore(), keyStorePath, alias, password);
   }
 
 
-
-  /**
-   * Attempts to run the keytool utility with the provided arguments.
-   *
-   * @param  commandElements   The command and arguments to execute.  The first
-   *                           element of the array must be the command, and the
-   *                           remaining elements must be the arguments.
-   * @param  keyStorePassword  The password of the key store.
-   * @param  storePassword     The password of the certificate.
-   * @param  outputAcceptable  Indicates whether it is acceptable for the
-   *                           command to generate output, as long as the exit
-   *                           code is zero.  Some commands (like "keytool
-   *                           -import") may generate output even on successful
-   *                           completion.  If the command generates output and
-   *                           this is {@code false}, then an exception will
-   *                           be thrown.
-   *
-   * @throws  KeyStoreException  If a problem occurs while attempting to invoke
-   *                             the keytool utility, if it does not exit with
-   *                             the expected exit code, or if any unexpected
-   *                             output is generated while running the tool.
-   */
-  private void runKeyTool(String[] commandElements, String keyStorePassword,
-      String storePassword, boolean outputAcceptable)
-          throws KeyStoreException
-  {
-    String lineSeparator = System.getProperty("line.separator");
-    if (lineSeparator == null)
-    {
-      lineSeparator = "\n";
-    }
-    boolean keyStoreDefined;
-    File keyStoreFile = new File(keyStorePath);
-    keyStoreDefined = (keyStoreFile.exists() && (keyStoreFile.length() > 0)) ||
-      KEY_STORE_TYPE_PKCS11.equals(keyStoreType);
-
-    boolean isNewKeyStorePassword = !keyStoreDefined &&
-      (getGenKeyCommand().equalsIgnoreCase(commandElements[1]) ||
-      "-import".equalsIgnoreCase(commandElements[1]));
-
-    boolean isNewStorePassword =
-      getGenKeyCommand().equalsIgnoreCase(commandElements[1]);
-
-    boolean askForStorePassword =
-      !"-import".equalsIgnoreCase(commandElements[1]);
-
-    try
-    {
-      ProcessBuilder processBuilder = new ProcessBuilder(commandElements);
-      processBuilder.redirectErrorStream(true);
-
-      ByteArrayOutputStream output = new ByteArrayOutputStream();
-      byte[] buffer = new byte[1024];
-      Process process = processBuilder.start();
-      InputStream inputStream = process.getInputStream();
-      OutputStream out = process.getOutputStream();
-      if (!isJDK15() &&
-          (SetupUtils.getOperatingSystem() == OperatingSystem.AIX))
-      {
-        // This is required when using JDK 1.6 on AIX to be able to write
-        // on the OutputStream.
-        try
-        {
-          Thread.sleep(1500);
-        } catch (Throwable t) {}
-      }
-      out.write(keyStorePassword.getBytes()) ;
-      out.write(lineSeparator.getBytes()) ;
-      out.flush() ;
-      // With Java6 and above, keytool asks for the password twice.
-      if (!isJDK15() && isNewKeyStorePassword)
-      {
-        if (SetupUtils.getOperatingSystem() == OperatingSystem.AIX)
-        {
-          // This is required when using JDK 1.6 on AIX to be able to write
-          // on the OutputStream.
-          try
-          {
-            Thread.sleep(1500);
-          } catch (Throwable t) {}
-        }
-        out.write(keyStorePassword.getBytes()) ;
-        out.write(lineSeparator.getBytes()) ;
-        out.flush() ;
-      }
-
-      if (askForStorePassword)
-      {
-        out.write(storePassword.getBytes()) ;
-        out.write(lineSeparator.getBytes()) ;
-        out.flush() ;
-
-        // With Java6 and above, keytool asks for the password twice (if we
-        // are not running AIX).
-        if (!isJDK15() && isNewStorePassword &&
-            (SetupUtils.getOperatingSystem() != OperatingSystem.AIX))
-        {
-          out.write(storePassword.getBytes()) ;
-          out.write(lineSeparator.getBytes()) ;
-          out.flush() ;
-        }
-      }
-      // Close the output stream since it can generate a deadlock on IBM JVM
-      // (issue 2795).
-      out.close();
-      while (true)
-      {
-        int bytesRead = inputStream.read(buffer);
-        if (bytesRead < 0)
-        {
-          break;
-        }
-        else if (bytesRead > 0)
-        {
-          output.write(buffer, 0, bytesRead);
-        }
-      }
-      process.waitFor();
-      int exitValue = process.exitValue();
-      byte[] outputBytes = output.toByteArray();
-      if (exitValue != 0)
-      {
-        // FIXME -- Make this an internationalizeable string.
-        StringBuilder message = new StringBuilder();
-        message.append("Unexpected exit code of ");
-        message.append(exitValue);
-        message.append(" returned from the keytool utility.");
-
-        if ((outputBytes != null) && (outputBytes.length > 0))
-        {
-          message.append("  The generated output was:  '");
-          message.append(new String(outputBytes));
-          message.append("'.");
-        }
-
-        throw new KeyStoreException(message.toString());
-      }
-      else if ((! outputAcceptable) && (outputBytes != null) &&
-               (outputBytes.length > 0))
-      {
-        // FIXME -- Make this an internationalizeable string.
-        StringBuilder message = new StringBuilder();
-        message.append("Unexpected output generated by the keytool " +
-                       "utility:  '");
-        message.append(new String(outputBytes));
-        message.append("'.");
-
-        throw new KeyStoreException(message.toString());
-      }
-    }
-    catch (KeyStoreException kse)
-    {
-      throw kse;
-    }
-    catch (Exception e)
-    {
-      // FIXME -- Make this an internationalizeable string.
-      throw new KeyStoreException("Could not invoke the KeyTool.run method:  " +
-                                  e, e);
-    }
-  }
-
-
-
   /**
    * Retrieves a handle to the key store.
    *
@@ -888,97 +382,74 @@
    *                             key store.
    */
   private KeyStore getKeyStore()
-          throws KeyStoreException
+  throws KeyStoreException
   {
-    if (keyStore != null)
-    {
-      return keyStore;
-    }
-
-    // For JKS, JCEKS and PKCS12 key stores, we should make sure the file
-    // exists, and we'll need an input stream that we can use to read it.
-    // For PKCS11 key stores there won't be a file and the input stream should
-    // be null.
-    FileInputStream keyStoreInputStream = null;
-    if (keyStoreType.equals(KEY_STORE_TYPE_JKS) ||
-        keyStoreType.equals(KEY_STORE_TYPE_JCEKS) ||
-        keyStoreType.equals(KEY_STORE_TYPE_PKCS12))
-    {
-      File keyStoreFile = new File(keyStorePath);
-      if (! keyStoreFile.exists())
+      if (keyStore != null)
       {
-        return null;
+          return keyStore;
       }
 
+      // For JKS and PKCS12 key stores, we should make sure the file exists, and
+      // we'll need an input stream that we can use to read it.  For PKCS11 key
+      // stores there won't be a file and the input stream should be null.
+      FileInputStream keyStoreInputStream = null;
+      if (keyStoreType.equals(KEY_STORE_TYPE_JKS) ||
+          keyStoreType.equals(KEY_STORE_TYPE_JCEKS) ||
+          keyStoreType.equals(KEY_STORE_TYPE_PKCS12))
+      {
+          final File keyStoreFile = new File(keyStorePath);
+          if (! keyStoreFile.exists())
+          {
+              return null;
+          }
+
+          try
+          {
+              keyStoreInputStream = new FileInputStream(keyStoreFile);
+          }
+          catch (final Exception e)
+          {
+              throw new KeyStoreException(String.valueOf(e), e);
+          }
+      }
+
+
+      final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
       try
       {
-        keyStoreInputStream = new FileInputStream(keyStoreFile);
+          keyStore.load(keyStoreInputStream, password);
+          return this.keyStore = keyStore;
       }
-      catch (Exception e)
+      catch (final Exception e)
       {
-        throw new KeyStoreException(String.valueOf(e), e);
+          throw new KeyStoreException(String.valueOf(e), e);
       }
-    }
-
-
-    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
-    try
-    {
-      keyStore.load(keyStoreInputStream, keyStorePIN.toCharArray());
-      return this.keyStore = keyStore;
-    }
-    catch (Exception e)
-    {
-      throw new KeyStoreException(String.valueOf(e), e);
-    }
-    finally
-    {
-      if (keyStoreInputStream != null)
+      finally
       {
-        try
-        {
-          keyStoreInputStream.close();
-        }
-        catch (Throwable t)
-        {
-        }
+          if (keyStoreInputStream != null)
+          {
+              try
+              {
+                  keyStoreInputStream.close();
+              }
+              catch (final Throwable t)
+              {
+              }
+          }
       }
+  }
+
+  private static void ensureFileValid(File arg, String msgStr) {
+    if(arg == null) {
+      Message msg = ERR_CERTMGR_FILE_NAME_INVALID.get(msgStr);
+      throw new NullPointerException(msg.toString());
     }
   }
 
-  /**
-   * Returns whether we are running JDK 1.5 or not.
-   * @return <CODE>true</CODE> if we are running JDK 1.5 and <CODE>false</CODE>
-   * otherwise.
-   */
-  private boolean isJDK15()
-  {
-    boolean isJDK15 = false;
-    try
-    {
-      String javaRelease = System.getProperty ("java.version");
-      isJDK15 = javaRelease.startsWith("1.5");
+  private static void ensureValid(String arg, String msgStr) {
+    if(arg == null || arg.length() == 0) {
+     Message msg = ERR_CERTMGR_VALUE_INVALID.get(msgStr);
+      throw new NullPointerException(msg.toString());
     }
-    catch (Throwable t)
-    {
-      System.err.println("Cannot get the java version: " + t);
-    }
-    return isJDK15;
-  }
-
-  private String getGenKeyCommand()
-  {
-    String genKeyCommand;
-    if (!isJDK15())
-    {
-      genKeyCommand = "-genkeypair";
-    }
-    else
-    {
-      genKeyCommand = "-genkey";
-    }
-    return genKeyCommand;
   }
 }
-
-
diff --git a/opends/src/server/org/opends/server/util/Platform.java b/opends/src/server/org/opends/server/util/Platform.java
new file mode 100644
index 0000000..d5ce295
--- /dev/null
+++ b/opends/src/server/org/opends/server/util/Platform.java
@@ -0,0 +1,683 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.util;
+
+
+import java.security.KeyStoreException;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import org.opends.messages.Message;
+import static org.opends.messages.UtilityMessages.*;
+
+/**
+ * Provides a wrapper class that collects all of the JVM vendor
+ * and JDK version specific code in a single place.
+ *
+ */
+public final class Platform {
+
+   //Prefix that determines which security package to use.
+    private static String pkgPrefix;
+
+    //IBM security package doesn't appear to support PCKS10, this flags turns
+    //off support for that.
+    private static boolean certReqAllowed;
+
+    //The two security package prefixes (IBM and SUN).
+    private static final String IBM_SEC = "com.ibm.security";
+    private static final String SUN_SEC = "sun.security";
+
+    private static final PlatformIMPL IMPL;
+
+    static {
+     String vendor = System.getProperty("java.vendor");
+     String ver = System.getProperty("java.version");
+
+      if(vendor.startsWith("IBM"))
+      {
+        pkgPrefix = IBM_SEC;
+        certReqAllowed = false;
+        if(ver.startsWith("1.5"))
+        {
+          IMPL = new IBM5PlatformIMPL();
+        }
+        else
+        {
+          IMPL = new DefaultPlatformIMPL();
+        }
+      }
+      else
+      {
+        pkgPrefix = SUN_SEC;
+        certReqAllowed = true;
+        if(ver.startsWith("1.5"))
+        {
+         IMPL = new Sun5PlatformIMPL();
+        }
+        else
+        {
+          IMPL = new DefaultPlatformIMPL();
+        }
+      }
+    }
+
+   /**
+    * Platform base class. Performs all of the certificate management functions.
+    */
+    private abstract static class PlatformIMPL {
+
+        //Key size, key algorithm and signature algorithms used.
+        private static final  int KEY_SIZE = 1024;
+        private static final String KEY_ALGORITHM = "rsa";
+        private static final String SIG_ALGORITHM = "SHA1WithRSA";
+
+        //Time values used in validity calculations.
+        private static final int SEC_IN_DAY = 24 * 60 * 60;
+        private static final int DEFAULT_VALIDITY = 90 * SEC_IN_DAY;
+
+        //These two are used to build certificate request files.
+        private static final String TMPFILE_PREFIX = "CertificateManager-";
+        private static final String TMPFILE_EXT = ".csr";
+
+        //Methods pulled from the classes.
+        private static final String ENCODE_SIGN_METHOD = "encodeAndSign";
+        private static final String GENERATE_METHOD = "generate";
+        private static final String GET_PRIVATE_KEY_METHOD = "getPrivateKey";
+        private static final String GET_SELFSIGNED_CERT_METHOD =
+                                                          "getSelfCertificate";
+        private static final String PRINT_METHOD = "print";
+
+        //Classes needed to manage certificates.
+        private static Class<?> certKeyGenClass, X500NameClass,
+                                X500SignerClass, PKCS10Class;
+
+        //Constructors for each of the above classes.
+        private static Constructor<?> certKeyGenCons, X500NameCons,
+                                      X500SignerCons, pkcs10Cons;
+
+        static {
+          String x509pkg = pkgPrefix + ".x509";
+          String pkcs10Pkg = pkgPrefix + ".pkcs";
+          String certAndKeyGen=  x509pkg + ".CertAndKeyGen";
+          String X500Name =  x509pkg + ".X500Name";
+          String X500Signer = x509pkg + ".X500Signer";
+          try {
+            certKeyGenClass = Class.forName(certAndKeyGen);
+            X500NameClass = Class.forName(X500Name);
+            X500SignerClass = Class.forName(X500Signer);
+            if(certReqAllowed) {
+              String pkcs10 = pkcs10Pkg + ".PKCS10";
+              PKCS10Class = Class.forName(pkcs10);
+              pkcs10Cons = PKCS10Class.getConstructor(PublicKey.class);
+            }
+            certKeyGenCons =
+                    certKeyGenClass.getConstructor(String.class, String.class);
+            X500NameCons = X500NameClass.getConstructor(String.class);
+            X500SignerCons =
+                 X500SignerClass.getConstructor(Signature.class, X500NameClass);
+          } catch (ClassNotFoundException e) {
+            Message msg = ERR_CERTMGR_CLASS_NOT_FOUND.get(e.getMessage());
+            throw new ExceptionInInitializerError(msg.toString());
+          } catch (SecurityException e) {
+            Message msg = ERR_CERTMGR_SECURITY.get(e.getMessage());
+            throw new ExceptionInInitializerError(msg.toString());
+          } catch (NoSuchMethodException e) {
+            Message msg = ERR_CERTMGR_NO_METHOD.get(e.getMessage());
+            throw new ExceptionInInitializerError(msg.toString());
+          }
+        }
+
+        protected PlatformIMPL() {}
+
+        /**
+         * Generate a certificate request. Note that this methods checks if
+         * the certificate request generation is allowed and throws an
+         * exception if it isn't supported. Some vendors JDKs aren't compatible
+         * with Sun's certificate request generation classes so they aren't
+         * supported.
+         *
+         * @param ks The keystore to use in the request creation.
+         * @param ksType The keystore type.
+         * @param ksPath The path to the keystore.
+         * @param alias The alias to use in the request generation.
+         * @param pwd The keystore password to use.
+         * @param dn A dn string to use as the certificate subject.
+         *
+         * @return A file object pointing at the created certificate request.
+         * @throws KeyStoreException If the certificate request failed.
+         */
+        public final File
+        generateCertificateRequest(KeyStore ks, String ksType, String ksPath,
+            String alias, char[] pwd, String dn) throws KeyStoreException {
+          if(!certReqAllowed) {
+            String vendor = System.getProperty("java.vendor");
+            Message msg =
+              ERR_CERTMGR_CERT_SIGN_REQ_NOT_SUPPORTED.get(vendor);
+            throw new KeyStoreException(msg.toString());
+          }
+          KeyStore keyStore = generateSelfSignedCertificate(ks, ksType, ksPath,
+                                            alias, pwd, dn, DEFAULT_VALIDITY);
+          File csrFile;
+          try {
+            csrFile = File.createTempFile(TMPFILE_PREFIX, TMPFILE_EXT);
+            csrFile.deleteOnExit();
+            PrintStream printStream =
+              new PrintStream(new FileOutputStream(csrFile.getAbsolutePath()));
+            if(keyStore == null) {
+              Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get();
+              throw new KeyStoreException(msg.toString());
+            }
+            PrivateKey privateKey = getPrivateKey(keyStore, alias, pwd);
+            if(privateKey == null) {
+              Message msg =  ERR_CERTMGR_PRIVATE_KEY.get(alias);
+              throw new KeyStoreException(msg.toString());
+            }
+            Certificate cert = keyStore.getCertificate(alias);
+            if(cert == null) {
+              Message msg = ERR_CERTMGR_ALIAS_NO_CERTIFICATE.get(alias);
+              throw new KeyStoreException(msg.toString());
+            }
+            Signature signature = Signature.getInstance(SIG_ALGORITHM);
+            signature.initSign(privateKey);
+            Object request = pkcs10Cons.newInstance(cert.getPublicKey());
+            Object subject = X500NameCons.newInstance(dn);
+            Object signer =
+              X500SignerCons.newInstance(signature, subject);
+            Method encodeAndSign =
+              PKCS10Class.getMethod(ENCODE_SIGN_METHOD, X500SignerClass);
+            Method print =
+              PKCS10Class.getMethod(PRINT_METHOD, PrintStream.class);
+            encodeAndSign.invoke(request, signer);
+            print.invoke(request, printStream);
+            printStream.close();
+          } catch (Exception e) {
+            Message msg = ERR_CERTMGR_CERT_REQUEST.get(alias,e.getMessage());
+            throw new KeyStoreException(msg.toString());
+          }
+          return csrFile;
+        }
+
+        /**
+         * Delete the specified alias from the specified keystore.
+         *
+         * @param ks The keystore to delete the alias from.
+         * @param ksPath The path to the keystore.
+         * @param alias The alias to use in the request generation.
+         * @param pwd The keystore password to use.
+         *
+         * @throws KeyStoreException If an error occurred deleting the alias.
+         */
+        public final void deleteAlias(KeyStore ks, String ksPath,
+            String alias, char[] pwd) throws KeyStoreException {
+              try {
+                  if(ks == null) {
+                      Message msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get();
+                      throw new KeyStoreException(msg.toString());
+                  }
+                  ks.deleteEntry(alias);
+                  FileOutputStream fs = new FileOutputStream(ksPath);
+                  ks.store(fs, pwd);
+                  fs.close();
+              } catch (Exception e) {
+                  Message msg =
+                      ERR_CERTMGR_DELETE_ALIAS.get(alias,e.getMessage());
+                  throw new KeyStoreException(msg.toString());
+              }
+        }
+
+        /**
+         * Add the certificate in the specified path to the specified keystore,
+         * creating the keystore using the specified type and path if it the
+         * keystore doesn't exist.
+         *
+         * @param ks The keystore to add the certificate to, may be null if it
+         *           doesn't exist.
+         * @param ksType The type to use if the keystore is created.
+         * @param ksPath The path to the keystore if it is created.
+         * @param alias The alias to store the certificate under.
+         * @param pwd The password to use in saving the certificate.
+         * @param certPath The path to the file containing the certificate.
+         * @throws KeyStoreException If an error occurred adding the
+         *                           certificate to the keystore.
+         */
+        public final void addCertificate(KeyStore ks, String ksType,
+            String ksPath, String alias, char[] pwd, String certPath)
+        throws KeyStoreException {
+          try {
+            CertificateFactory cf = CertificateFactory.getInstance("X509");
+            InputStream inStream = new FileInputStream(certPath);
+            if(ks == null) {
+              ks = KeyStore.getInstance(ksType);
+              ks.load(null, pwd);
+            }
+            //Do not support certificate replies.
+            if (ks.entryInstanceOf(alias ,KeyStore.PrivateKeyEntry.class)) {
+              Message msg = ERR_CERTMGR_CERT_REPLIES_INVALID.get(alias);
+              throw new KeyStoreException(msg.toString());
+            } else if(!ks.containsAlias(alias) ||
+                ks.entryInstanceOf(alias,
+                    KeyStore.TrustedCertificateEntry.class))
+              trustedCert(alias, cf, ks, inStream);
+            else {
+              Message msg = ERR_CERTMGR_ALIAS_INVALID.get(alias);
+              throw new KeyStoreException(msg.toString());
+            }
+            FileOutputStream fileOutStream = new FileOutputStream(ksPath);
+            ks.store(fileOutStream, pwd);
+            fileOutStream.close();
+            inStream.close();
+          } catch (Exception e) {
+            Message msg =
+              ERR_CERTMGR_ADD_CERT.get(alias, e.getMessage());
+            throw new KeyStoreException(msg.toString());
+          }
+        }
+
+        /**
+         * Generate a self-signed certificate using the specified alias, dn
+         * string and validity period. If the keystore does not exist, create it
+         * using the specified type and path.
+         *
+         * @param ks The keystore to save the certificate in. May be null if it
+         *           does not exist.
+         * @param ksType The keystore type to use if the keystore is created.
+         * @param ksPath The path to the keystore if the keystore is created.
+         * @param alias The alias to store the certificate under.
+         * @param pwd The password to us in saving the certificate.
+         * @param dn The dn string used as the certificate subject.
+         * @param validity The validity of the certificate in days.
+         * @return The keystore that the self-signed certificate was stored in.
+         *
+         * @throws KeyStoreException If the self-signed certificate cannot be
+         *                           generated.
+         */
+        public final
+        KeyStore generateSelfSignedCertificate(KeyStore ks, String ksType,
+            String ksPath, String alias, char[] pwd, String dn, int validity)
+        throws KeyStoreException {
+          try {
+            if(ks == null) {
+              ks = KeyStore.getInstance(ksType);
+              ks.load(null, pwd);
+            } else if(ks.containsAlias(alias)) {
+              Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias);
+              throw new KeyStoreException(msg.toString());
+            }
+            Object keypair =
+              certKeyGenCons.newInstance(KEY_ALGORITHM, SIG_ALGORITHM);
+            Object subject = X500NameCons.newInstance(dn);
+            Method certAndKeyGenGenerate =
+              certKeyGenClass.getMethod(GENERATE_METHOD, int.class);
+            certAndKeyGenGenerate.invoke(keypair, KEY_SIZE);
+            Method certAndKeyGetPrivateKey =
+              certKeyGenClass.getMethod(GET_PRIVATE_KEY_METHOD);
+            PrivateKey privatevKey =
+              (PrivateKey) certAndKeyGetPrivateKey.invoke(keypair);
+            Certificate[] certificateChain = new Certificate[1];
+            Method getSelfCertificate =
+              certKeyGenClass.getMethod(GET_SELFSIGNED_CERT_METHOD,
+                                        X500NameClass,long.class);
+            int days = validity * SEC_IN_DAY;
+            certificateChain[0] =
+              (Certificate) getSelfCertificate.invoke(keypair, subject, days);
+            ks.setKeyEntry(alias, privatevKey, pwd, certificateChain);
+            FileOutputStream fileOutStream = new FileOutputStream(ksPath);
+            ks.store(fileOutStream, pwd);
+            fileOutStream.close();
+          } catch (Exception e) {
+            Message msg =
+                   ERR_CERTMGR_GEN_SELF_SIGNED_CERT.get(alias, e.getMessage());
+            throw new KeyStoreException(msg.toString());
+          }
+          return ks;
+        }
+
+        /**
+         * Generate a x509 certificate from the input stream. Verification is
+         * done only if it is self-signed.
+         *
+         * @param alias The alias to save the certificate under.
+         * @param cf The x509 certificate factory.
+         * @param ks The keystore to add the certificate in.
+         * @param in The input stream to read the certificate from.
+         * @throws KeyStoreException If the alias exists already in the
+         *         keystore, if the self-signed certificate didn't verify, or
+         *         the certificate could not be stored.
+         */
+        private void trustedCert(String alias, CertificateFactory cf,
+             KeyStore ks, InputStream in) throws KeyStoreException {
+          try {
+            if (ks.containsAlias(alias) == true) {
+              Message msg = ERR_CERTMGR_ALIAS_ALREADY_EXISTS.get(alias);
+              throw new KeyStoreException(msg.toString());
+            }
+            X509Certificate cert = (X509Certificate) cf.generateCertificate(in);
+            if (isSelfSigned(cert))
+              cert.verify(cert.getPublicKey());
+            ks.setCertificateEntry(alias, cert);
+          } catch (Exception e) {
+            Message msg =
+              ERR_CERTMGR_TRUSTED_CERT.get(alias,e.getMessage());
+            throw new KeyStoreException(msg.toString());
+          }
+        }
+
+        /**
+         * Check that the issuer and subject DNs match.
+         *
+         * @param cert The certificate to examine.
+         * @return {@code true} if the certificate is self-signed.
+         */
+        private boolean isSelfSigned(X509Certificate cert) {
+          return cert.getSubjectDN().equals(cert.getIssuerDN());
+        }
+
+        /**
+         * Returns the private key associated with specified alias and keystore.
+         * The keystore was already checked for existance.
+         *
+         * @param ks The keystore to get the private key from, it must exist.
+         * @param alias The alias to get the private key of.
+         * @param pwd The password used to get the key from the keystore.
+         * @return The private key of related to the alias.
+         *
+         * @throws KeyStoreException If the alias is not in the keystore, the
+         *    entry related to the alias is not of
+         */
+        private PrivateKey getPrivateKey(KeyStore ks, String alias, char[] pwd)
+        throws KeyStoreException  {
+            PrivateKey key = null;
+            try {
+                if(!ks.containsAlias(alias)) {
+                    Message msg = ERR_CERTMGR_ALIAS_DOES_NOT_EXIST.get(alias);
+                    throw new KeyStoreException(msg.toString());
+                }
+                if(!ks.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class) &&
+                  !ks.entryInstanceOf(alias, KeyStore.SecretKeyEntry.class)) {
+                    Message msg =
+                                ERR_CERTMGR_ALIAS_INVALID_ENTRY_TYPE.get(alias);
+                    throw new KeyStoreException(msg.toString());
+                }
+                key = (PrivateKey)ks.getKey(alias, pwd);
+            } catch (Exception  e) {
+                Message msg =
+                    ERR_CERTMGR_GET_KEY.get(alias,e.getMessage());
+                throw new KeyStoreException(msg.toString());
+            }
+            return key;
+        }
+
+        /**
+         * Normalize the data in the specified buffer.
+         *
+         * @param buffer The buffer to normalize.
+         */
+         public abstract void normalize(StringBuilder buffer);
+    }
+
+    //Prevent instantiation.
+    private Platform() {}
+
+    /**
+     * Add the certificate in the specified path to the provided keystore;
+     * creating the keystore with the provided type and path if it doesn't
+     * exist.
+     *
+     * @param ks The keystore to add the certificate to, may be null if it
+     *           doesn't exist.
+     * @param ksType The type to use if the keystore is created.
+     * @param ksPath The path to the keystore if it is created.
+     * @param alias The alias to store the certificate under.
+     * @param pwd The password to use in saving the certificate.
+     * @param certPath The path to the file containing the certificate.
+     *
+     * @throws KeyStoreException If an error occurred adding the
+     *                           certificate to the keystore.
+     */
+    public static void addCertificate(KeyStore ks, String ksType, String ksPath,
+        String alias, char[] pwd, String certPath) throws KeyStoreException {
+        IMPL.addCertificate(ks,ksType, ksPath, alias, pwd, certPath);
+    }
+
+
+    /**
+     * Delete the specified alias from the provided keystore.
+     *
+     * @param ks The keystore to delete the alias from.
+     * @param ksPath The path to the keystore.
+     * @param alias The alias to use in the request generation.
+     * @param pwd The keystore password to use.
+     *
+     * @throws KeyStoreException If an error occurred deleting the alias.
+     */
+    public static void deleteAlias(KeyStore ks, String ksPath, String alias,
+        char[] pwd) throws KeyStoreException {
+        IMPL.deleteAlias(ks, ksPath, alias, pwd);
+    }
+
+
+    /**
+     * Generate a certificate request using the specified parameters.
+     *
+     * @param ks The keystore to use in the request creation.
+     * @param ksType The keystore type.
+     * @param ksPath The path to the keystore.
+     * @param alias The alias to use in the request generation.
+     * @param pwd The keystore password to use.
+     * @param dn A dn string to use as the certificate subject.
+     * @return A file object pointing at the created certificate request.
+     *
+     * @throws KeyStoreException If the certificate request failed.
+     */
+    public static File generateCertificateRequest(KeyStore ks, String ksType,
+        String ksPath, String alias, char[] pwd, String dn)
+    throws KeyStoreException {
+        return IMPL.generateCertificateRequest(ks, ksType, ksPath, alias,
+                                               pwd, dn);
+    }
+
+
+    /**
+     * Generate a self-signed certificate using the specified alias, dn
+     * string and validity period. If the keystore does not exist, it will be
+     * created using the specified keystore type and path.
+     *
+     * @param ks The keystore to save the certificate in. May be null if it
+     *           does not exist.
+     * @param ksType The keystore type to use if the keystore is created.
+     * @param ksPath The path to the keystore if the keystore is created.
+     * @param alias The alias to store the certificate under.
+     * @param pwd The password to us in saving the certificate.
+     * @param dn The dn string used as the certificate subject.
+     * @param validity The validity of the certificate in days.
+     *
+     * @throws KeyStoreException If the self-signed certificate cannot be
+     *                           generated.
+     */
+    public static void generateSelfSignedCertificate(KeyStore ks, String ksType,
+        String ksPath, String alias, char[] pwd, String dn, int validity)
+    throws KeyStoreException {
+        IMPL.generateSelfSignedCertificate(ks, ksType, ksPath, alias, pwd, dn,
+                                      validity);
+    }
+
+
+
+    /**
+     * Sun 5 JDK platform class.
+     */
+    private static class Sun5PlatformIMPL extends PlatformIMPL
+   {
+       //normalize method.
+      private static final Method NORMALIZE;
+      //Normalized form method.
+      private static final Object FORM_NFKC;
+
+      static
+      {
+        Method normalize = null;
+        Object formNFKC = null;
+        try
+        {
+          Class<?> normalizer = Class.forName("sun.text.Normalizer");
+          formNFKC = normalizer.getField("DECOMP_COMPAT").get(null);
+          Class<?> normalizerForm = Class.forName("sun.text.Normalizer$Mode");
+          normalize = normalizer.getMethod("normalize", String.class,
+                 normalizerForm, Integer.TYPE);
+        }
+        catch (Exception ex)
+        {
+        // Do not use Normalizer. The values are already set to null.
+        }
+      NORMALIZE = normalize;
+      FORM_NFKC = formNFKC;
+     }
+
+     private Sun5PlatformIMPL()
+     {
+       super();
+     }
+
+      @Override
+      public void normalize(StringBuilder buffer)
+      {
+        try
+        {
+          String normal =
+               (String) NORMALIZE.invoke(null, buffer.toString(), FORM_NFKC,0);
+          buffer.replace(0,buffer.length(),normal);
+        }
+        catch(Exception ex)
+        {
+          //Don't do anything. buffer should be used.
+        }
+      }
+   }
+
+    /**
+     * Default platform class.
+     */
+     private static class DefaultPlatformIMPL extends PlatformIMPL
+   {
+       //normalize method.
+      private static final Method NORMALIZE;
+      //Normalized form method.
+      private static final Object FORM_NFKC;
+
+      static
+      {
+        Method normalize = null;
+        Object formNFKC = null;
+        try
+        {
+          Class<?> normalizer = Class.forName("java.text.Normalizer");
+          Class<?> normalizerForm = Class.forName("java.text.Normalizer$Form");
+          normalize = normalizer.getMethod("normalize", CharSequence.class,
+                normalizerForm);
+          formNFKC = normalizerForm.getField("NFKD").get(null);
+        }
+        catch (Exception ex)
+        {
+        // Do not use Normalizer. The values are already set to null.
+        }
+        NORMALIZE = normalize;
+        FORM_NFKC = formNFKC;
+     }
+
+     private DefaultPlatformIMPL()
+     {
+       super();
+     }
+
+      @Override
+      public void normalize(StringBuilder buffer)
+      {
+        try
+        {
+          String normal = (String) NORMALIZE.invoke(null, buffer, FORM_NFKC);
+          buffer.replace(0,buffer.length(),normal);
+        }
+        catch(Exception ex)
+        {
+          //Don't do anything. buffer should be used.
+        }
+      }
+   }
+
+   /**
+    * IBM JDK 5 platform class.
+    */
+   private static class IBM5PlatformIMPL extends PlatformIMPL
+   {
+   private IBM5PlatformIMPL()
+     {
+       super();
+     }
+    @Override
+    public void normalize(StringBuilder buffer)
+    {
+      //No implementation.
+    }
+   }
+
+   /**
+    * Normalize the specified buffer.
+    *
+    * @param buffer The buffer to normalize.
+    */
+   public static void normalize(StringBuilder buffer)
+   {
+     IMPL.normalize(buffer);
+   }
+
+   /**
+    * Test if a platform java vendor property starts with the specified
+    * vendor string.
+    *
+    * @param vendor The vendor to check for.
+    * @return {@code true} if the java vendor starts with the specified vendor
+    *         string.
+    */
+   public static boolean isVendor(String vendor) {
+     String javaVendor = System.getProperty("java.vendor");
+     return javaVendor.startsWith(vendor);
+   }
+}
+
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/CertificateManagerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/CertificateManagerTestCase.java
index c71a573..fe1b2be 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/util/CertificateManagerTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/util/CertificateManagerTestCase.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2008 Sun Microsystems, Inc.
+ *      Copyright 2008-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.util;
 
@@ -920,7 +920,7 @@
   public void testGenerateCSRAliasInUse()
          throws Exception
   {
-    if (! CERT_MANAGER_AVAILABLE)
+    if (! CERT_MANAGER_AVAILABLE || Platform.isVendor("IBM"))
     {
       return;
     }
@@ -1002,7 +1002,7 @@
   public void testGenerateCSRInvalidSubject()
          throws Exception
   {
-    if (! CERT_MANAGER_AVAILABLE)
+    if (! CERT_MANAGER_AVAILABLE || Platform.isVendor("IBM"))
     {
       return;
     }
@@ -1037,7 +1037,7 @@
   public void testGenerateCSRJKS()
          throws Exception
   {
-    if (! CERT_MANAGER_AVAILABLE)
+    if (! CERT_MANAGER_AVAILABLE || Platform.isVendor("IBM"))
     {
       return;
     }
@@ -1068,7 +1068,7 @@
   public void testGenerateCSRPKCS12()
          throws Exception
   {
-    if (! CERT_MANAGER_AVAILABLE)
+    if (! CERT_MANAGER_AVAILABLE || Platform.isVendor("IBM"))
     {
       return;
     }

--
Gitblit v1.10.0