From 77a17e4cb35b6232e8fab371bdd735e6f53bd7a1 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Thu, 19 Apr 2007 18:55:16 +0000
Subject: [PATCH] The following changes are targetted to extend the Graphical Setup and provide the possibility of configuring SSL and Start TLS.

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java                     |  390 ++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java                            |    4 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java                                |   17 
 opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureDS.java                               |  404 +++++++
 opendj-sdk/opends/build.xml                                                                         |    2 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java                  |   86 +
 opendj-sdk/opends/resource/FindJavaHome.class                                                       |    0 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java              |   17 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java                     |    6 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java                            |    1 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java                    |  275 ++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java                         |  356 ++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java                                |   86 +
 opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java                         |    2 
 opendj-sdk/opends/src/server/org/opends/server/util/CertificateManager.java                         |   15 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java                  |  160 ++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java                | 1188 +++++++++++++++++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java         |   35 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java |    2 
 opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java                           |  185 +++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties               |  100 +
 opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java                       |   12 
 22 files changed, 3,293 insertions(+), 50 deletions(-)

diff --git a/opendj-sdk/opends/build.xml b/opendj-sdk/opends/build.xml
index 8505da3..761871e 100644
--- a/opendj-sdk/opends/build.xml
+++ b/opendj-sdk/opends/build.xml
@@ -457,6 +457,7 @@
                target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
                memoryMaximumSize="${MEM}">
       <include name="**/org/opends/server/util/SetupUtils.java"/>
+    	<include name="**/org/opends/server/util/CertificateManager.java"/>
       <include name="**/org/opends/server/util/DynamicConstants.java"/>
       <include name="**/org/opends/server/types/OperatingSystem.java"/>
       <compilerarg value="-Xlint:all" />
@@ -561,6 +562,7 @@
                        target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
                        memoryMaximumSize="${MEM}">
       <include name="**/org/opends/server/util/SetupUtils.java"/>
+    	<include name="**/org/opends/server/util/CertificateManager.java"/>
       <include name="**/org/opends/server/util/DynamicConstants.java"/>
       <include name="**/org/opends/server/types/OperatingSystem.java"/>
       <compilerarg value="-Xlint:all" />
diff --git a/opendj-sdk/opends/resource/FindJavaHome.class b/opendj-sdk/opends/resource/FindJavaHome.class
index 02356df..c0ae713 100644
--- a/opendj-sdk/opends/resource/FindJavaHome.class
+++ b/opendj-sdk/opends/resource/FindJavaHome.class
Binary files differ
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
index bd65bc9..607b803 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
@@ -141,10 +141,17 @@
     {
       public void run()
       {
-        // Setup MacOSX native menu bar before AWT is loaded.
-        Utils.setMacOSXMenuBar(getFrameTitle());
-        SplashScreen.main(args);
-        returnValue[0] = 0;
+        try
+        {
+          // Setup MacOSX native menu bar before AWT is loaded.
+          Utils.setMacOSXMenuBar(getFrameTitle());
+          SplashScreen.main(args);
+          returnValue[0] = 0;
+        }
+        catch (Throwable t)
+        {
+          t.printStackTrace();
+        }
       }
     });
     /*
@@ -152,7 +159,7 @@
      * problems with the display environment.
      */
     PrintStream printStream = System.err;
-    System.setErr(new EmptyPrintStream());
+    //System.setErr(new EmptyPrintStream());
     t.start();
     try
     {
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
new file mode 100644
index 0000000..0826303
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
@@ -0,0 +1,356 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+package org.opends.quicksetup;
+
+/**
+ * Class used to describe the Security Options specified by the user.
+ *
+ */
+public class SecurityOptions
+{
+  private boolean enableSSL;
+  private boolean enableStartTLS;
+
+  private int sslPort = 636;
+
+  /**
+   * The different type of security options that we can have.
+   */
+  public enum CertificateType
+  {
+    /**
+     * No certificate to be used (and so no SSL and no Start TLS).
+     */
+    NO_CERTIFICATE,
+    /**
+     * Use a newly created Self Signed Certificate.
+     */
+    SELF_SIGNED_CERTIFICATE,
+    /**
+     * Use an existing JKS keystore.
+     */
+    JKS,
+    /**
+     * Use an existing PKCS#11 keystore.
+     */
+    PKCS11,
+    /**
+     * Use an existing PKCS#12 keystore.
+     */
+    PKCS12
+  }
+
+  private CertificateType certificateType;
+
+  private String selfSignedCertificateName;
+  private String keyStorePath;
+  private String keyStorePassword;
+  private String aliasToUse;
+
+  private SecurityOptions()
+  {
+  }
+
+  /**
+   * Creates a new instance of a SecurityOptions representing for no certificate
+   * (no SSL or Start TLS).
+   * @return a new instance of a SecurityOptions representing for no certificate
+   * (no SSL or Start TLS).
+   */
+  public static SecurityOptions createNoCertificateOptions()
+  {
+    SecurityOptions ops = new SecurityOptions();
+    ops.setCertificateType(CertificateType.NO_CERTIFICATE);
+    ops.setEnableSSL(false);
+    ops.setEnableStartTLS(false);
+    return ops;
+  }
+
+  /**
+   * Creates a new instance of a SecurityOptions using a self-signed
+   * certificate.
+   * @param name the name of the certificate (the CN value).
+   * @param enableSSL whether SSL is enabled or not.
+   * @param enableStartTLS whether Start TLS is enabled or not.
+   * @param sslPort the value of the LDAPS port.
+   * @return a new instance of a SecurityOptions using a self-signed
+   * certificate.
+   */
+  public static SecurityOptions createSelfSignedCertificateOptions(String name,
+      boolean enableSSL, boolean enableStartTLS, int sslPort)
+  {
+    SecurityOptions ops = new SecurityOptions();
+    ops.setCertificateType(CertificateType.SELF_SIGNED_CERTIFICATE);
+    ops.setSelfSignedCertificateName(name);
+    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort, null);
+    return ops;
+  }
+
+  /**
+   * Creates a new instance of a SecurityOptions using a Java Key Store.
+   * @param keystorePath the path of the key store.
+   * @param keystorePwd the password of the key store.
+   * @param enableSSL whether SSL is enabled or not.
+   * @param enableStartTLS whether Start TLS is enabled or not.
+   * @param sslPort the value of the LDAPS port.
+   * @param aliasToUse the alias of the certificate in the keystore to be used.
+   * @return a new instance of a SecurityOptions using a Java Key Store.
+   */
+  public static SecurityOptions createJKSCertificateOptions(String keystorePath,
+      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
+      int sslPort, String aliasToUse)
+  {
+    SecurityOptions ops = new SecurityOptions();
+    ops.setCertificateType(CertificateType.JKS);
+    ops.setKeyStorePath(keystorePath);
+    ops.setKeyStorePassword(keystorePwd);
+    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
+        aliasToUse);
+    return ops;
+  }
+
+  /**
+   * Creates a new instance of a SecurityOptions using a PKCS#11 Key Store.
+   * @param keystorePwd the password of the key store.
+   * @param enableSSL whether SSL is enabled or not.
+   * @param enableStartTLS whether Start TLS is enabled or not.
+   * @param sslPort the value of the LDAPS port.
+   * @param aliasToUse the alias of the certificate in the keystore to be used.
+   * @return a new instance of a SecurityOptions using a PKCS#11 Key Store.
+   */
+  public static SecurityOptions createPKCS11CertificateOptions(
+      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
+      int sslPort, String aliasToUse)
+  {
+    SecurityOptions ops = new SecurityOptions();
+    ops.setCertificateType(CertificateType.PKCS11);
+    ops.setKeyStorePassword(keystorePwd);
+    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
+        aliasToUse);
+    return ops;
+  }
+
+  /**
+   * Creates a new instance of a SecurityOptions using a PKCS#12 Key Store.
+   * @param keystorePath the path of the key store.
+   * @param keystorePwd the password of the key store.
+   * @param enableSSL whether SSL is enabled or not.
+   * @param enableStartTLS whether Start TLS is enabled or not.
+   * @param sslPort the value of the LDAPS port.
+   * @param aliasToUse the alias of the certificate in the keystore to be used.
+   * @return a new instance of a SecurityOptions using a PKCS#12 Key Store.
+   */
+  public static SecurityOptions createPKCS12CertificateOptions(
+      String keystorePath, String keystorePwd, boolean enableSSL,
+      boolean enableStartTLS, int sslPort, String aliasToUse)
+  {
+    SecurityOptions ops = new SecurityOptions();
+    ops.setCertificateType(CertificateType.PKCS12);
+    ops.setKeyStorePath(keystorePath);
+    ops.setKeyStorePassword(keystorePwd);
+    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
+        aliasToUse);
+    return ops;
+  }
+
+  /**
+   * Returns the CertificateType for this instance.
+   * @return the CertificateType for this instance.
+   */
+  public CertificateType getCertificateType()
+  {
+    return certificateType;
+  }
+
+  /**
+   * Sets the CertificateType for this instance.
+   * @param certificateType the CertificateType for this instance.
+   */
+  private void setCertificateType(CertificateType certificateType)
+  {
+    this.certificateType = certificateType;
+  }
+
+  /**
+   * Returns whether SSL is enabled or not.
+   * @return <CODE>true</CODE> if SSL is enabled and <CODE>false</CODE>
+   * otherwise.
+   */
+  public boolean getEnableSSL()
+  {
+    return enableSSL;
+  }
+
+  /**
+   * Sets whether SSL is enabled or not.
+   * @param enableSSL whether SSL is enabled or not.
+   */
+  private void setEnableSSL(boolean enableSSL)
+  {
+    this.enableSSL = enableSSL;
+  }
+
+  /**
+   * Returns whether StartTLS is enabled or not.
+   * @return <CODE>true</CODE> if StartTLS is enabled and <CODE>false</CODE>
+   * otherwise.
+   */
+  public boolean getEnableStartTLS()
+  {
+    return enableStartTLS;
+  }
+
+  /**
+   * Sets whether StartTLS is enabled or not.
+   * @param enableStartTLS whether StartTLS is enabled or not.
+   */
+  private void setEnableStartTLS(boolean enableStartTLS)
+  {
+    this.enableStartTLS = enableStartTLS;
+  }
+
+  /**
+   * Returns the key store password.
+   * @return the key store password.
+   */
+  public String getKeystorePassword()
+  {
+    return keyStorePassword;
+  }
+
+  /**
+   * Sets the key store password.
+   * @param keystorePassword the new key store password.
+   */
+  private void setKeyStorePassword(String keyStorePassword)
+  {
+    this.keyStorePassword = keyStorePassword;
+  }
+
+  /**
+   * Returns the key store path.
+   * @return the key store path.
+   */
+  public String getKeystorePath()
+  {
+    return keyStorePath;
+  }
+
+  /**
+   * Sets the key store path.
+   * @param keyStorePath the new key store path.
+   */
+  private void setKeyStorePath(String keyStorePath)
+  {
+    this.keyStorePath = keyStorePath;
+  }
+
+  /**
+   * Returns the self-signed certificate name.
+   * @return the self-signed certificate name.
+   */
+  public String getSelfSignedCertificateName()
+  {
+    return selfSignedCertificateName;
+  }
+
+  /**
+   * Sets the self-signed certificate name.
+   * @param selfSignedCertificateName the new self-signed certificate name.
+   */
+  private void setSelfSignedCertificateName(String selfSignedCertificateName)
+  {
+    this.selfSignedCertificateName = selfSignedCertificateName;
+  }
+
+  /**
+   * Updates the provided certificate options object with some parameters.
+   * @param ops the SecurityOptions object to be updated.
+   * @param enableSSL whether to enable SSL or not.
+   * @param enableStartTLS whether to enable StartTLS or not.
+   * @param sslPort the LDAPS port number.
+   * @param aliasToUse the name of the alias to be used.
+   */
+  private static void updateCertificateOptions(SecurityOptions ops,
+      boolean enableSSL, boolean enableStartTLS, int sslPort, String aliasToUse)
+  {
+    if (!enableSSL && !enableStartTLS)
+    {
+      throw new IllegalArgumentException(
+          "You must enable SSL or StartTLS to use a certificate.");
+    }
+    ops.setEnableSSL(enableSSL);
+    ops.setEnableStartTLS(enableStartTLS);
+    ops.setSslPort(sslPort);
+    ops.setAliasToUse(aliasToUse);
+  }
+
+  /**
+   * Returns the SSL port.
+   * @return the SSL port.
+   */
+  public int getSslPort()
+  {
+    return sslPort;
+  }
+
+  /**
+   * Sets the SSL port.
+   * @param sslPort the new SSL port.
+   */
+  void setSslPort(int sslPort)
+  {
+    this.sslPort = sslPort;
+  }
+
+  /**
+   * Sets the Self-Signed certificate name (the CN).
+   * @param selfSignedCertificateName the new Self-Signed certificate name.
+   */
+  void setCertificateUserName(String selfSignedCertificateName)
+  {
+    this.selfSignedCertificateName = selfSignedCertificateName;
+  }
+
+  /**
+   * Returns the alias of the certificate in the keystore to be used.
+   * @return the alias of the certificate in the keystore to be used.
+   */
+  public String getAliasToUse()
+  {
+    return aliasToUse;
+  }
+
+  /**
+   * Sets the certificate alias name.
+   * @param aliasToUse the certificate alias name.
+   */
+  void setAliasToUse(String aliasToUse)
+  {
+    this.aliasToUse = aliasToUse;
+  }
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index 59791bc..35834cd 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -40,6 +40,7 @@
   private String directoryManagerDn;
   private String directoryManagerPwd;
   private DataOptions dataOptions;
+  private SecurityOptions securityOptions;
   private int serverJMXPort;
   private boolean startServer;
   private boolean stopServer;
@@ -63,6 +64,10 @@
     setDirectoryManagerDn("cn=Directory Manager");
 
     setDataOptions(defaultDataOptions);
+    SecurityOptions sec = SecurityOptions.createNoCertificateOptions();
+    sec.setSslPort(getDefaultSslPort());
+    sec.setCertificateUserName(getDefaultSelfSignedName());
+    setSecurityOptions(sec);
   }
 
   /**
@@ -219,11 +224,34 @@
   }
 
   /**
+   * Returns the SecurityOptions representing the SSL/StartTLS configuration
+   * chosen by the user.
+   * @return the SecurityOptions representing the SSL/StartTLS configuration
+   * chosen by the user.
+   */
+  public SecurityOptions getSecurityOptions()
+  {
+    return securityOptions;
+  }
+
+  /**
+   * Sets the SecurityOptions representing the SSL/StartTLS configuration
+   * chosen by the user.
+   * @param securityOptions the SecurityOptions representing the SSL/StartTLS
+   * configuration chosen by the user.
+   */
+  public void setSecurityOptions(SecurityOptions securityOptions)
+  {
+    this.securityOptions = securityOptions;
+  }
+
+  /**
    * Provides the port that will be proposed to the user in the second page of
-   * the installation wizard. It will check whether we can use 389 and if not it
-   * will return -1.
+   * the installation wizard. It will check whether we can use ports of type
+   * X389 and if not it will return -1.
    *
-   * @return the port 389 if it is available and we can use and -1 if not.
+   * @return the free port of type x389 if it is available and we can use and -1
+   * if not.
    */
   static public int getDefaultPort()
   {
@@ -241,18 +269,50 @@
   }
 
   /**
+   * Provides the port that will be proposed to the user in the security dialog
+   *  of the installation wizard. It will check whether we can use ports of type
+   * X636 and if not it will return -1.
+   *
+   * @return the free port of type X636 if it is available and we can use and -1
+   * if not.
+   */
+  static int getDefaultSslPort()
+  {
+    int defaultPort = -1;
+
+    for (int i=0;i<10000 && (defaultPort == -1);i+=1000)
+    {
+      int port = i + 636;
+      if (Utils.canUseAsPort(port))
+      {
+        defaultPort = port;
+      }
+    }
+    return defaultPort;
+  }
+
+  /**
    * Provides the port that will be used by default for JMX.
    *
+   * @param forbiddenPorts an array of ports that we cannot use.
    * @return the port X689 if it is available and we can use and -1 if not.
    */
-  static public int getDefaultJMXPort()
+  static public int getDefaultJMXPort(int[] forbiddenPorts)
   {
     int defaultJMXPort = -1;
 
     for (int i=0;i<65000 && (defaultJMXPort == -1);i+=1000)
     {
       int port = i + SetupUtils.getDefaultJMXPort();
-      if (Utils.canUseAsPort(port))
+      boolean isForbidden = false;
+      if (forbiddenPorts != null)
+      {
+        for (int j=0; j<forbiddenPorts.length && !isForbidden; j++)
+        {
+          isForbidden = forbiddenPorts[j] == port;
+        }
+      }
+      if (!isForbidden && Utils.canUseAsPort(port))
       {
         defaultJMXPort = port;
       }
@@ -260,4 +320,20 @@
     return defaultJMXPort;
   }
 
+  /**
+   * Provides the default name for the self signed certificate that will be
+   * created.
+   */
+  private String getDefaultSelfSignedName()
+  {
+    String name = "";
+    try
+    {
+      name = java.net.InetAddress.getLocalHost().getHostName();
+    }
+    catch (Throwable t)
+    {
+    }
+    return name;
+  }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java
index 67c3412..1a4caf5 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/event/BrowseActionListener.java
@@ -72,7 +72,11 @@
     /**
      * The Browser is used to retrieve an LDIF file.
      */
-    OPEN_LDIF_FILE
+    OPEN_LDIF_FILE,
+    /**
+     * The Browser is used to retrieve a generic file.
+     */
+    GENERIC_FILE
   }
 
   /**
@@ -117,6 +121,13 @@
       fc.setFileFilter(ldifFiles);
       break;
 
+    case GENERIC_FILE:
+      fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+      fc.setDialogType(JFileChooser.OPEN_DIALOG);
+      fc.setDialogTitle(i18n.getMsg("open-generic-file-dialog-title"));
+
+      break;
+
     default:
       throw new IllegalArgumentException("Unknown BrowseType: " + type);
     }
@@ -162,6 +173,10 @@
       returnVal = fc.showOpenDialog(parent);
       break;
 
+    case GENERIC_FILE:
+      returnVal = fc.showOpenDialog(parent);
+      break;
+
     default:
       throw new IllegalStateException("Unknown type: " + type);
     }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index 75184f9..3a5a4c9 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -29,16 +29,22 @@
 import static org.opends.quicksetup.Step.*;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
 import java.util.*;
 import java.awt.event.WindowEvent;
 
 import org.opends.quicksetup.ui.*;
 import org.opends.quicksetup.util.Utils;
 import org.opends.quicksetup.*;
+import org.opends.server.util.CertificateManager;
 import org.opends.quicksetup.installer.ui.InstallReviewPanel;
 import org.opends.server.util.SetupUtils;
 
+import javax.naming.ldap.Rdn;
 import javax.swing.*;
 
 
@@ -66,9 +72,15 @@
   // Constants used to do checks
   private static final int MIN_DIRECTORY_MANAGER_PWD = 1;
 
-  private static final int MIN_PORT_VALUE = 1;
+  /**
+   * The minimum integer value that can be used for a port.
+   */
+  public static final int MIN_PORT_VALUE = 1;
 
-  private static final int MAX_PORT_VALUE = 65535;
+  /**
+   * The maximum integer value that can be used for a port.
+   */
+  public static final int MAX_PORT_VALUE = 65535;
 
   private static final int MIN_NUMBER_ENTRIES = 1;
 
@@ -440,6 +452,65 @@
     argList.add(Utils.getPath(getInstallation().getCurrentConfigurationFile()));
     argList.add("-p");
     argList.add(String.valueOf(getUserData().getServerPort()));
+
+    SecurityOptions sec = getUserData().getSecurityOptions();
+    if (sec.getEnableSSL())
+    {
+      argList.add("-P");
+      argList.add(String.valueOf(sec.getSslPort()));
+    }
+
+    if (sec.getEnableStartTLS())
+    {
+      argList.add("-q");
+    }
+
+    switch (sec.getCertificateType())
+    {
+    case SELF_SIGNED_CERTIFICATE:
+      argList.add("-k");
+      argList.add("cn=JKS,cn=Key Manager Providers,cn=config");
+      argList.add("-t");
+      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
+      break;
+    case JKS:
+      argList.add("-k");
+      argList.add("cn=JKS,cn=Key Manager Providers,cn=config");
+      argList.add("-t");
+      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
+      argList.add("-m");
+      argList.add(sec.getKeystorePath());
+      argList.add("-a");
+      argList.add(sec.getAliasToUse());
+      break;
+    case PKCS12:
+      argList.add("-k");
+      argList.add("cn=PKCS12,cn=Key Manager Providers,cn=config");
+      argList.add("-t");
+      // We are going to import the PCKS12 certificate in a JKS truststore
+      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
+      argList.add("-m");
+      argList.add(sec.getKeystorePath());
+      argList.add("-a");
+      argList.add(sec.getAliasToUse());
+      break;
+    case PKCS11:
+      argList.add("-k");
+      argList.add("cn=PKCS11,cn=Key Manager Providers,cn=config");
+      argList.add("-t");
+      // We are going to import the PCKS11 certificate in a JKS truststore
+      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
+      argList.add("-a");
+      argList.add(sec.getAliasToUse());
+      break;
+    case NO_CERTIFICATE:
+      // Nothing to do.
+      break;
+    default:
+      throw new IllegalStateException("Unknown certificate type: "+
+          sec.getCertificateType());
+    }
+
     argList.add("-x");
     argList.add(String.valueOf(getUserData().getServerJMXPort()));
 
@@ -471,6 +542,113 @@
           QuickSetupException.Type.CONFIGURATION_ERROR,
           getThrowableMsg("error-configuring", null, t), t);
     }
+
+    try
+    {
+      SecurityOptions.CertificateType certType = sec.getCertificateType();
+      if (certType != SecurityOptions.CertificateType.NO_CERTIFICATE)
+      {
+        notifyListeners(getLineBreak());
+        notifyListeners(getFormattedWithPoints(
+            getMsg("progress-updating-certificates")));
+      }
+      CertificateManager certManager;
+      CertificateManager trustManager;
+      File f;
+      switch (certType)
+      {
+      case NO_CERTIFICATE:
+        // Nothing to do
+        break;
+      case SELF_SIGNED_CERTIFICATE:
+        String pwd = getSelfSignedCertificatePwd();
+        certManager = new CertificateManager(
+            getSelfSignedKeystorePath(),
+            CertificateManager.KEY_STORE_TYPE_JKS,
+            pwd);
+        certManager.generateSelfSignedCertificate("server-cert",
+            getSelfSignedCertificateSubjectDN(sec),
+            getSelfSignedCertificateValidity());
+        exportCertificate(certManager, "server-cert",
+            getTemporaryCertificatePath());
+
+        trustManager = new CertificateManager(
+            getTrustManagerPath(),
+            CertificateManager.KEY_STORE_TYPE_JKS,
+            pwd);
+        trustManager.addCertificate("server-cert",
+            new File(getTemporaryCertificatePath()));
+        Utils.createFile(getKeystorePinPath(), pwd);
+        f = new File(getTemporaryCertificatePath());
+        f.delete();
+
+        break;
+      case JKS:
+        certManager = new CertificateManager(
+            sec.getKeystorePath(),
+            CertificateManager.KEY_STORE_TYPE_JKS,
+            sec.getKeystorePassword());
+        exportCertificate(certManager, sec.getAliasToUse(),
+            getTemporaryCertificatePath());
+
+        trustManager = new CertificateManager(
+            getTrustManagerPath(),
+            CertificateManager.KEY_STORE_TYPE_JKS,
+            sec.getKeystorePassword());
+        trustManager.addCertificate(sec.getAliasToUse(),
+            new File(getTemporaryCertificatePath()));
+        Utils.createFile(getKeystorePinPath(), sec.getKeystorePassword());
+        f = new File(getTemporaryCertificatePath());
+        f.delete();
+        break;
+      case PKCS12:
+        certManager = new CertificateManager(
+            sec.getKeystorePath(),
+            CertificateManager.KEY_STORE_TYPE_PKCS12,
+            sec.getKeystorePassword());
+        exportCertificate(certManager, sec.getAliasToUse(),
+            getTemporaryCertificatePath());
+
+        trustManager = new CertificateManager(
+            getTrustManagerPath(),
+            CertificateManager.KEY_STORE_TYPE_JKS,
+            sec.getKeystorePassword());
+        trustManager.addCertificate(sec.getAliasToUse(),
+            new File(getTemporaryCertificatePath()));
+        Utils.createFile(getKeystorePinPath(), sec.getKeystorePassword());
+        f = new File(getTemporaryCertificatePath());
+        f.delete();
+        break;
+      case PKCS11:
+        certManager = new CertificateManager(
+            CertificateManager.KEY_STORE_PATH_PKCS11,
+            CertificateManager.KEY_STORE_TYPE_PKCS11,
+            sec.getKeystorePassword());
+        exportCertificate(certManager, sec.getAliasToUse(),
+            getTemporaryCertificatePath());
+
+        trustManager = new CertificateManager(
+            getTrustManagerPath(),
+            CertificateManager.KEY_STORE_TYPE_JKS,
+            sec.getKeystorePassword());
+        trustManager.addCertificate(sec.getAliasToUse(),
+            new File(getTemporaryCertificatePath()));
+        Utils.createFile(getKeystorePinPath(), sec.getKeystorePassword());
+        break;
+      default:
+        throw new IllegalStateException("Unknown certificate type: "+certType);
+      }
+      if (certType != SecurityOptions.CertificateType.NO_CERTIFICATE)
+      {
+        notifyListeners(getFormattedDone());
+      }
+    }
+    catch (Throwable t)
+    {
+      throw new QuickSetupException(
+          QuickSetupException.Type.CONFIGURATION_ERROR,
+          getThrowableMsg("error-configuring-certificate", null, t), t);
+    }
   }
 
   /**
@@ -535,7 +713,7 @@
     String[] arg =
       { getUserData().getDataOptions().getLDIFPath() };
     notifyListeners(getFormattedProgress(getMsg("progress-importing-ldif", arg))
-        + formatter.getLineBreak());
+        + getLineBreak());
 
     ArrayList<String> argList = new ArrayList<String>();
     argList.add("-C");
@@ -582,7 +760,7 @@
       { String.valueOf(nEntries) };
     notifyListeners(getFormattedProgress(getMsg(
         "progress-import-automatically-generated", arg))
-        + formatter.getLineBreak());
+        + getLineBreak());
 
     ArrayList<String> argList = new ArrayList<String>();
     argList.add("-C");
@@ -783,9 +961,10 @@
 
     // Check the port
     String sPort = qs.getFieldStringValue(FieldName.SERVER_PORT);
+    int port = -1;
     try
     {
-      int port = Integer.parseInt(sPort);
+      port = Integer.parseInt(sPort);
       if ((port < MIN_PORT_VALUE) || (port > MAX_PORT_VALUE))
       {
         String[] args =
@@ -819,6 +998,52 @@
       qs.displayFieldInvalid(FieldName.SERVER_PORT, true);
     }
 
+    // Check the secure port
+    SecurityOptions sec =
+      (SecurityOptions)qs.getFieldValue(FieldName.SECURITY_OPTIONS);
+    int securePort = sec.getSslPort();
+    if (sec.getEnableSSL())
+    {
+      if ((securePort < MIN_PORT_VALUE) || (securePort > MAX_PORT_VALUE))
+      {
+        String[] args =
+          { String.valueOf(MIN_PORT_VALUE), String.valueOf(MAX_PORT_VALUE) };
+        errorMsgs.add(getMsg("invalid-secure-port-value-range", args));
+        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, true);
+      } else if (!Utils.canUseAsPort(securePort))
+      {
+        if (Utils.isPriviledgedPort(securePort))
+        {
+          errorMsgs.add(getMsg("cannot-bind-priviledged-port", new String[]
+            { String.valueOf(securePort) }));
+        } else
+        {
+          errorMsgs.add(getMsg("cannot-bind-port", new String[]
+            { String.valueOf(securePort) }));
+        }
+        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, true);
+
+      }
+      else if (port == securePort)
+      {
+        errorMsgs.add(getMsg("equal-ports",
+            new String[] { String.valueOf(securePort) }));
+        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, true);
+        qs.displayFieldInvalid(FieldName.SERVER_PORT, true);
+      }
+      else
+      {
+        getUserData().setSecurityOptions(sec);
+        qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, false);
+      }
+    }
+    else
+    {
+      getUserData().setSecurityOptions(sec);
+      qs.displayFieldInvalid(FieldName.SECURITY_OPTIONS, false);
+    }
+
+
     // Check the Directory Manager DN
     String dmDn = qs.getFieldStringValue(FieldName.DIRECTORY_MANAGER_DN);
 
@@ -876,7 +1101,8 @@
       qs.displayFieldInvalid(FieldName.DIRECTORY_MANAGER_PWD_CONFIRM, false);
     }
 
-    int defaultJMXPort = UserData.getDefaultJMXPort();
+    int defaultJMXPort =
+      UserData.getDefaultJMXPort(new int[] {port, securePort});
     if (defaultJMXPort != -1)
     {
       getUserData().setServerJMXPort(defaultJMXPort);
@@ -1035,4 +1261,156 @@
     return 15 * 1024 * 1024;
   }
 
+  /**
+   * Returns the keystore path to be used for generating a self-signed
+   * certificate.
+   * @return the keystore path to be used for generating a self-signed
+   * certificate.
+   */
+  private String getSelfSignedKeystorePath()
+  {
+    String parentFile = Utils.getPath(getInstallationPath(),
+        Installation.CONFIG_PATH_RELATIVE);
+    return (Utils.getPath(parentFile, "keystore"));
+  }
+
+  /**
+   * Returns the trustmanager path to be used for generating a self-signed
+   * certificate.
+   * @return the trustmanager path to be used for generating a self-signed
+   * certificate.
+   */
+  private String getTrustManagerPath()
+  {
+    String parentFile = Utils.getPath(getInstallationPath(),
+        Installation.CONFIG_PATH_RELATIVE);
+    return (Utils.getPath(parentFile, "truststore"));
+  }
+
+  /**
+   * Returns the path of the self-signed that we export to be able to create
+   * a truststore.
+   * @return the path of the self-signed that is exported.
+   */
+  private String getTemporaryCertificatePath()
+  {
+    String parentFile = Utils.getPath(getInstallationPath(),
+        Installation.CONFIG_PATH_RELATIVE);
+    return (Utils.getPath(parentFile, "server-cert.txt"));
+  }
+
+  /**
+   * Returns the path to be used to store the password of the keystore.
+   * @return the path to be used to store the password of the keystore.
+   */
+  private String getKeystorePinPath()
+  {
+    String parentFile = Utils.getPath(getInstallationPath(),
+        Installation.CONFIG_PATH_RELATIVE);
+    return (Utils.getPath(parentFile, "keystore.pin"));
+  }
+
+
+  /**
+   * Returns the validity period to be used to generate the self-signed
+   * certificate.
+   * @return the validity period to be used to generate the self-signed
+   * certificate.
+   */
+  private int getSelfSignedCertificateValidity()
+  {
+    return 2 * 365;
+  }
+
+  /**
+   * Returns the Subject DN to be used to generate the self-signed certificate.
+   * @return the Subject DN to be used to generate the self-signed certificate.
+   */
+  private String getSelfSignedCertificateSubjectDN(SecurityOptions sec)
+  {
+    return "cn="+Rdn.escapeValue(sec.getSelfSignedCertificateName())+
+    ",O=OpenDS Self-Signed Certificate";
+  }
+
+  /**
+   * Returns a randomly generated password for the self-signed certificate
+   * keystore.
+   * @return a randomly generated password for the self-signed certificate
+   * keystore.
+   */
+  private String getSelfSignedCertificatePwd()
+  {
+    int pwdLength = 50;
+    char[] pwd = new char[pwdLength];
+    Random random = new Random();
+    for (int pos=0; pos < pwdLength; pos++) {
+        int type = getRandomInt(random,3);
+        char nextChar = getRandomChar(random,type);
+        pwd[pos] = nextChar;
+    }
+
+    String pwdString = new String(pwd);
+    return pwdString;
+  }
+
+  private void exportCertificate(CertificateManager certManager, String alias,
+      String path) throws CertificateEncodingException, IOException,
+      KeyStoreException
+  {
+    Certificate certificate = certManager.getCertificate(alias);
+
+    byte[] certificateBytes = certificate.getEncoded();
+
+    FileOutputStream outputStream = new FileOutputStream(path, false);
+    outputStream.write(certificateBytes);
+    outputStream.close();
+  }
+
+  /* The next two methods are used to generate the random password for the
+   * self-signed certificate. */
+  private char getRandomChar(Random random, int type)
+  {
+    char generatedChar;
+    int next = random.nextInt();
+    int d;
+
+    switch (type)
+    {
+    case 0:
+      // Will return a figure
+      d = next % 10;
+      if (d < 0)
+      {
+        d = d * (-1);
+      }
+      generatedChar = (char) (d+48);
+      break;
+    case 1:
+      // Will return a lower case letter
+      d = next % 26;
+      if (d < 0)
+      {
+        d = d * (-1);
+      }
+      generatedChar =  (char) (d + 97);
+      break;
+    default:
+      // Will return a capital letter
+      d = (next % 26);
+      if (d < 0)
+      {
+        d = d * (-1);
+      }
+      generatedChar = (char) (d + 65) ;
+    }
+
+    return generatedChar;
+  }
+
+  private static int getRandomInt(Random random,int modulo)
+  {
+    int value = 0;
+    value = (random.nextInt() & modulo);
+    return value;
+  }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
index 5adcdff..d0229db 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -73,8 +73,10 @@
     {
       setFieldValue(FieldName.SERVER_LOCATION, userData.getServerLocation());
     }
-    setFieldValue(FieldName.SERVER_PORT, String.valueOf(userData
-        .getServerPort()));
+    setFieldValue(FieldName.SERVER_PORT,
+        String.valueOf(userData.getServerPort()));
+    setFieldValue(FieldName.SECURITY_OPTIONS,
+        getSecurityOptionsString(userData.getSecurityOptions(), false));
     setFieldValue(FieldName.DIRECTORY_MANAGER_DN, userData
         .getDirectoryManagerDn());
     setFieldValue(FieldName.DIRECTORY_BASE_DN, userData.getDataOptions()
@@ -133,6 +135,11 @@
         LabelFieldDescriptor.FieldType.READ_ONLY,
         LabelFieldDescriptor.LabelType.PRIMARY, 0));
 
+    hm.put(FieldName.SECURITY_OPTIONS, new LabelFieldDescriptor(
+        getMsg("server-security-label"), getMsg("server-security-tooltip"),
+        LabelFieldDescriptor.FieldType.READ_ONLY,
+        LabelFieldDescriptor.LabelType.PRIMARY, 0));
+
     hm.put(FieldName.DIRECTORY_MANAGER_DN, new LabelFieldDescriptor(
         getMsg("server-directory-manager-dn-label"),
         getMsg("server-directory-manager-dn-tooltip"),
@@ -248,17 +255,23 @@
     if (displayServerLocation)
     {
       fieldNames =
-          new FieldName[]
-            { FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
-                FieldName.DIRECTORY_MANAGER_DN,
-                FieldName.DIRECTORY_BASE_DN,
-                FieldName.DATA_OPTIONS };
-    } else
+        new FieldName[]
+          {
+            FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
+            FieldName.SECURITY_OPTIONS, FieldName.DIRECTORY_MANAGER_DN,
+            FieldName.DIRECTORY_BASE_DN,
+            FieldName.DATA_OPTIONS
+          };
+    }
+    else
     {
       fieldNames =
-          new FieldName[]
-            { FieldName.SERVER_PORT, FieldName.DIRECTORY_MANAGER_DN,
-                FieldName.DIRECTORY_BASE_DN, FieldName.DATA_OPTIONS };
+        new FieldName[]
+          {
+            FieldName.SERVER_PORT, FieldName.SECURITY_OPTIONS,
+            FieldName.DIRECTORY_MANAGER_DN,
+            FieldName.DIRECTORY_BASE_DN, FieldName.DATA_OPTIONS
+          };
     }
 
     for (int i = 0; i < fieldNames.length; i++)
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index dc168cb..12008b6 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -284,11 +284,14 @@
 least {1} megabytes of free disk space are required to install OpenDS.
 invalid-port-value-range=The LDAP Listener Port must be an integer between \
 {0} and {1}.
+invalid-secure-port-value-range=The LDAPS Listener Port must be an \
+integer between {0} and {1}.
 cannot-bind-priviledged-port=Cannot bind to privileged port {0}.\n\nThe port \
 could be already in use by another application or maybe you do not have the \
 rights to access it.
 cannot-bind-port=Cannot bind to port {0}.\n\nThe port could be already in use \
 by another application or maybe you do not have the rights to access it.
+equal-ports=You must specify different ports LDAP and LDAPS communication.
 empty-directory-manager-dn=You must provide an Administrative User DN.
 not-a-directory-manager-dn=The provided Administrative User DN is not a valid \
 DN.
@@ -428,6 +431,13 @@
 server-port-label=LDAP Listener Port:
 server-port-tooltip=Enter the port number that the server will use to listen \
 for LDAP requests
+server-security-label=LDAP Secure Access:
+server-security-tooltip=The LDAP Secure Access Configuration for the new \
+OpenDS server.
+cannot-update-security-warning=Disabled.  A valid keytool command could not be \
+found.
+server-security-button-label=Configure...
+server-security-button-tooltip=Click to configure the LDAP Secure Access.
 server-directory-manager-dn-label=Administrative User DN:
 server-directory-manager-dn-tooltip=Enter the distinguished name (DN) of the \
 Administrative User account that will used for managing OpenDS
@@ -438,6 +448,91 @@
 server-directory-manager-pwd-confirm-tooltip=Re-enter the password for the \
 OpenDS Administrative User account
 cannot-use-default-port=Could not use 389. Port in use or user not authorized.
+cannot-use-default-secure-port=Could not use 636. Port in use or user not \
+authorized.
+no-security=disabled
+enable-starttls=Enable StartTLS
+enable-ssl=Enable SSL on LDAP Port {0}
+self-signed-certificate=Create a new Self-Signed Certificate
+jks-certificate=Use existing Java Key Store File
+pkcs11-certificate=Use existing PKCS#11 Token
+pkcs12-certificate=Use existing PKCS#12 File
+
+#
+# Security Options dialog specific labels
+#
+security-options-dialog-title=OpenDS QuickSetup
+security-options-title=Configure Secure Access
+security-options-instructions=Specify the options for enabling secure access \
+to the server.
+security-options-ok-button-tooltip=Close this dialog and accept configuration.
+security-options-cancel-button-tooltip=Close this dialog and discard \
+configuration.
+enable-ssl-label=Enable SSL on Port:
+enable-ssl-tooltip=Enables SSL on the specified port.
+ssl-port-textfield-tooltip=The LDAPS port.
+enable-starttls-label=Enable StartTLS for LDAP
+enable-starttls-tooltip=Allows encrypted communication over the standard \
+LDAP port.
+use-self-signed-label=Generate Self-Signed Certificate (recommended for \
+testing only)
+use-self-signed-tooltip=Create a new Self-Signed Certificate to encrypt \
+communication.
+self-signed-certificate-name-label=Host Name:
+self-signed-certificate-name-tooltip=The host name will be used to name the \
+certificate.
+use-existing-certificate-label=Use an Existing Certificate:
+use-existing-certificate-tooltip=Select this if you have already a certificate \
+you want the new server to use.
+keystore-type-label=Key Store Type:
+jks-certificate-label=Java Key Store (JKS) File
+jks-certificate-tooltip=Select this option if you have a JKS certificate.
+pkcs11-certificate-label=PKCS#11 Token
+pkcs11-certificate-tooltip=Select this option if you have a PKCS#11 token.
+pkcs12-certificate-label=PKCS#12 File
+pkcs12-certificate-tooltip=Select this option if you have a PKCS#12 certificate.
+keystore-path-label=Key Store Path:
+keystore-path-tooltip=Absolute path to the keystore.
+keystore-pwd-label=Key Store Password:
+keystore-pwd-tooltip=Provide the password required to access the existing \
+key store.
+ssl-access-label=SSL Access:
+starttls-access-label=StartTLS Access:
+certificate-label=Certificate:
+no-self-signed-cert-name-provided=You must provide the host name for the \
+Self-Signed Certificate.
+keystore-path-not-provided=You must provide the path of the key store.
+keystore-path-does-not-exist=The provided key store path does not exist.
+keystore-path-not-a-file=The provided key store path is not a file.
+keystore-pwd-empty=You must provide the password of the key store.
+error-accessing-jks-keystore=Could not access the JKS key store.  Check that \
+the contents of the file\ncorrespond to a valid JKS key store, that you have \
+access rights to it and\nthat the provided password is valid.
+error-accessing-pkcs11-keystore=Could not access the PKCS#11 key store.  Check \
+that is installed and that the\nprovided password is valid.
+error-accessing-pkcs12-keystore=Could not access the PKCS#12 key store.  Check \
+that the contents of the file\ncorrespond to a valid PKCS#12 key store, that \
+you have access rights to it and\nthat the provided password is valid.
+pkcs11-keystore-does-not-exist=No certificates for the PCKS#11 key store could \
+be found.  Check that is\ninstalled, that you have access rights to it and \
+that the key store contains certificates.
+pkcs12-keystore-does-not-exist=No certificates for the PCKS#12 key store could \
+be found.  Check that the\nprovided path and password are valid and that the \
+key store contains certificates.
+jks-keystore-does-not-exist=No certificates for the Java Key Store could be \
+found.  Check that the provided\npath is valid.
+
+#
+# Select Alias dialog specific labels
+#
+select-alias-title=OpenDS QuickSetup
+select-alias-msg=The provided Key Store contains multiple certificates.<br>\
+Select the alias of the certificate that you want to be used as Server \
+Certificate:
+select-alias-ok-button-tooltip=Close this dialog and accept \
+selected alias.
+select-alias-cancel-button-tooltip=Close this dialog and discard \
+selected alias.
 
 #
 # Data Options Panel specific labels
@@ -531,9 +626,10 @@
 #
 browse-button-label=Browse...
 browse-button-tooltip=Click to display a file system browser
-ldif-files-description=Lightweight Directory Interchange Format (*.ldif)
+ldif-files-description=LDAP Data Interchange Format (*.ldif)
 open-server-location-dialog-title=Choose Installation Path
 open-ldif-file-dialog-title=Choose an LDIF File
+open-generic-file-dialog-title=Choose a File
 
 #
 # Progress Summary Labels
@@ -608,6 +704,7 @@
 progress-points=.....
 progress-extracting=Extracting {0}
 progress-configuring=Configuring Directory Server
+progress-updating-certificates=Configuring Certificates
 downloading-ratio=Downloading: {0}% Completed.
 validating-ratio=Downloading: {0}% Completed - Validating file: {1} % Completed.
 upgrading-ratio=Downloading: {0}% Completed - Upgrading file: {1} % Completed.
@@ -648,6 +745,7 @@
 error-creating-temp-file=An error occurred creating the temporary file.
 error-writing-to-temp-file=An error occurred writing to temporary file {0}.
 error-configuring=Error Configuring Directory Server.
+error-configuring-certificate=Error Configuring Certificates.
 error-enabling-windows-service=Error Enabling Windows service.
 error-disabling-windows-service=Error Disabling Windows service.
 error-creating-base-entry=Error Creating Base Entry.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
index 86143a0..9ef09ec 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
@@ -187,9 +187,13 @@
     gbc.gridwidth = GridBagConstraints.REMAINDER;
     panel.add(auxPanel, gbc);
 
+    int h1 = getLabel(FieldName.DATA_OPTIONS).getPreferredSize().height;
+    int h2 = getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY).
+    getPreferredSize().height;
+    int additionalInset = Math.abs(h2 - h1) / 2;
     gbc.gridwidth = GridBagConstraints.RELATIVE;
     gbc.weightx = 0.0;
-    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
+    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD + additionalInset;
     gbc.insets.left = 0;
     gbc.anchor = GridBagConstraints.NORTHWEST;
     panel.add(getLabel(FieldName.DATA_OPTIONS), gbc);
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
index dfb302f..9855187 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
@@ -357,7 +357,7 @@
 
         } catch (NamingException ne)
         {
-          if (installStatus.isServerRunning())
+          if (CurrentInstallStatus.isServerRunning())
           {
             throw ne;
           }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
index 0fa8164..8a3fdf8 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
@@ -64,6 +64,10 @@
    */
   DIRECTORY_BASE_DN, // the value associated with this is a String
   /**
+  * The value associated with this is a SecurityOptions object.
+  */
+  SECURITY_OPTIONS,
+  /**
    * The value associated with this is a DataOptions.Type.
    */
   DATA_OPTIONS,
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
index 4ff3603..01ee001 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
@@ -44,6 +44,7 @@
 import org.opends.quicksetup.event.ButtonActionListener;
 import org.opends.quicksetup.event.ButtonEvent;
 import org.opends.quicksetup.ProgressDescriptor;
+import org.opends.quicksetup.SecurityOptions;
 import org.opends.quicksetup.UserData;
 import org.opends.quicksetup.util.HtmlProgressMessageFormatter;
 import org.opends.quicksetup.util.ProgressMessageFormatter;
@@ -391,6 +392,91 @@
   }
 
   /**
+   * Returns a localized String representation of the provided SecurityOptions
+   * object.
+   * @param ops the SecurityOptions object from which we want to obtain the
+   * String representation.
+   * @param html whether the resulting String must be in HTML or not.
+   * @return a localized String representation of the provided SecurityOptions
+   * object.
+   */
+  protected String getSecurityOptionsString(SecurityOptions ops, boolean html)
+  {
+    StringBuilder buf = new StringBuilder();
+
+    if (ops.getCertificateType() ==
+      SecurityOptions.CertificateType.NO_CERTIFICATE)
+    {
+      buf.append(getMsg("no-security"));
+    }
+    else
+    {
+      if (ops.getEnableStartTLS())
+      {
+        buf.append(getMsg("enable-starttls"));
+      }
+      if (ops.getEnableSSL())
+      {
+        if (buf.length() > 0)
+        {
+          if (html)
+          {
+            buf.append("<br>");
+          }
+          else
+          {
+            buf.append("\n");
+          }
+        }
+        String[] arg = new String[] {String.valueOf(ops.getSslPort())};
+        buf.append(getMsg("enable-ssl", arg));
+      }
+      if (html)
+      {
+        buf.append("<br>");
+      }
+      else
+      {
+        buf.append("\n");
+      }
+      String certMsg;
+      switch (ops.getCertificateType())
+      {
+      case SELF_SIGNED_CERTIFICATE:
+        certMsg = getMsg("self-signed-certificate");
+        break;
+
+      case JKS:
+        certMsg = getMsg("jks-certificate");
+        break;
+
+      case PKCS11:
+        certMsg = getMsg("pkcs11-certificate");
+        break;
+
+      case PKCS12:
+        certMsg = getMsg("pkcs12-certificate");
+        break;
+
+      default:
+        throw new IllegalStateException("Unknown certificate options type: "+
+            ops.getCertificateType());
+      }
+      buf.append(certMsg);
+    }
+
+    if (html)
+    {
+      return "<html>"+UIFactory.applyFontToHtml(buf.toString(),
+          UIFactory.SECONDARY_FIELD_VALID_FONT);
+    }
+    else
+    {
+      return buf.toString();
+    }
+  }
+
+  /**
    * Creates and returns the title panel.
    * @return the title panel.
    */
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java
new file mode 100644
index 0000000..c44d41e
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java
@@ -0,0 +1,1188 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.quicksetup.ui;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.security.KeyStoreException;
+import java.util.ArrayList;
+
+import javax.swing.Box;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JRadioButton;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+
+import org.opends.quicksetup.SecurityOptions;
+import org.opends.quicksetup.event.BrowseActionListener;
+import org.opends.quicksetup.event.MinimumSizeComponentListener;
+import org.opends.quicksetup.i18n.ResourceProvider;
+import org.opends.quicksetup.installer.Installer;
+import org.opends.quicksetup.util.BackgroundTask;
+import org.opends.quicksetup.util.Utils;
+import org.opends.server.util.CertificateManager;
+
+/**
+ * This class is a dialog that appears when the user wants to configure
+ * security parameters for the new OpenDS instance.
+ */
+public class SecurityOptionsDialog extends JDialog
+{
+  private static final long serialVersionUID = 4083707346899442215L;
+
+  private JCheckBox cbEnableSSL;
+  private JCheckBox cbEnableStartTLS;
+  private JTextField tfPort;
+  private JRadioButton rbUseSelfSignedCertificate;
+  private JRadioButton rbUseExistingCertificate;
+  private JLabel lSelfSignedName;
+  private JTextField tfSelfSignedName;
+  private JLabel lKeystoreType;
+  private JRadioButton rbPKCS11;
+  private JRadioButton rbJKS;
+  private JRadioButton rbPKCS12;
+  private JLabel lKeystorePath;
+  private JTextField tfKeystorePath;
+  private JButton browseButton;
+  private JLabel lKeystorePwd;
+  private JPasswordField tfKeystorePwd;
+
+  private JButton cancelButton;
+  private JButton okButton;
+
+  private SelectAliasDialog aliasDlg;
+
+  private boolean isCancelled = true;
+
+  private SecurityOptions securityOptions;
+
+  private String[] aliases;
+  private String selectedAlias;
+
+  private final int DEFAULT_PORT = 636;
+
+  /**
+   * Constructor of the SecurityOptionsDialog.
+   * @param parent the parent frame for this dialog.
+   * @param options the SecurityOptions used to populate this dialog.
+   * @throws IllegalArgumentException if options is null.
+   */
+  public SecurityOptionsDialog(JFrame parent, SecurityOptions options)
+  throws IllegalArgumentException
+  {
+    super(parent);
+    setTitle(getMsg("security-options-dialog-title"));
+    securityOptions = options;
+    getContentPane().add(createPanel());
+    pack();
+
+    updateContents();
+
+    int minWidth = (int) getPreferredSize().getWidth();
+    int minHeight = (int) getPreferredSize().getHeight();
+    addComponentListener(new MinimumSizeComponentListener(this, minWidth,
+        minHeight));
+    getRootPane().setDefaultButton(okButton);
+
+    addWindowListener(new WindowAdapter()
+    {
+      public void windowClosing(WindowEvent e)
+      {
+        cancelClicked();
+      }
+    });
+    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+    UIFactory.IconType ic;
+    if (Utils.isMacOS())
+    {
+      ic = UIFactory.IconType.MINIMIZED_MAC;
+    }
+    else
+    {
+      ic = UIFactory.IconType.MINIMIZED;
+    }
+    setIconImage(UIFactory.getImageIcon(ic).getImage());
+    Utils.centerOnComponent(this, parent);
+  }
+
+  /**
+   * Returns <CODE>true</CODE> if the user clicked on cancel and
+   * <CODE>false</CODE> otherwise.
+   * @return <CODE>true</CODE> if the user clicked on cancel and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean isCancelled()
+  {
+    return isCancelled;
+  }
+
+  /**
+   * Displays this dialog and populates its contents with the provided
+   * SecurityOptions object.
+   * @param options the SecurityOptions used to populate this dialog.
+   * @throws IllegalArgumentException if options is null.
+   */
+  public void display(SecurityOptions options) throws IllegalArgumentException
+  {
+    if (options == null)
+    {
+      throw new IllegalArgumentException("options parameter cannot be null.");
+    }
+    UIFactory.setTextStyle(cbEnableSSL,
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    UIFactory.setTextStyle(lSelfSignedName,
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    UIFactory.setTextStyle(lKeystorePath,
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    UIFactory.setTextStyle(lKeystorePwd,
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+
+    securityOptions = options;
+    updateContents();
+
+    isCancelled = true;
+
+    setVisible(true);
+  }
+
+  /**
+   * Returns the security options object representing the input of the user
+   * in this panel.
+   * @return the security options object representing the input of the user
+   * in this panel.
+   */
+  public SecurityOptions getSecurityOptions()
+  {
+    SecurityOptions ops;
+
+    boolean enableSSL = cbEnableSSL.isSelected();
+    boolean enableStartTLS = cbEnableStartTLS.isSelected();
+    if (enableSSL || enableStartTLS)
+    {
+      int sslPort = -1;
+      try
+      {
+        sslPort = Integer.parseInt(tfPort.getText());
+      }
+      catch (Throwable t)
+      {
+      }
+      if (rbUseSelfSignedCertificate.isSelected())
+      {
+        ops = SecurityOptions.createSelfSignedCertificateOptions(
+            tfSelfSignedName.getText(), enableSSL, enableStartTLS, sslPort);
+      }
+      else if (rbJKS.isSelected())
+      {
+        ops = SecurityOptions.createJKSCertificateOptions(
+            tfKeystorePath.getText(),
+            String.valueOf(tfKeystorePwd.getPassword()), enableSSL,
+            enableStartTLS, sslPort, selectedAlias);
+      }
+      else if (rbPKCS11.isSelected())
+      {
+        ops = SecurityOptions.createPKCS11CertificateOptions(
+            String.valueOf(tfKeystorePwd.getPassword()), enableSSL,
+            enableStartTLS, sslPort, selectedAlias);
+      }
+      else if (rbPKCS12.isSelected())
+      {
+        ops = SecurityOptions.createPKCS12CertificateOptions(
+            tfKeystorePath.getText(),
+            String.valueOf(tfKeystorePwd.getPassword()), enableSSL,
+            enableStartTLS, sslPort, selectedAlias);
+      }
+      else
+      {
+        throw new IllegalStateException("No certificate options selected.");
+      }
+    }
+    else
+    {
+      ops = SecurityOptions.createNoCertificateOptions();
+    }
+    return ops;
+  }
+
+  /**
+   * Creates and returns the panel of the dialog.
+   * @return the panel of the dialog.
+   */
+  private JPanel createPanel()
+  {
+    GridBagConstraints gbc = new GridBagConstraints();
+
+    JPanel contentPanel = new JPanel(new GridBagLayout());
+    contentPanel.setBackground(UIFactory.DEFAULT_BACKGROUND);
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.weightx = 1.0;
+
+    JPanel topPanel = new JPanel(new GridBagLayout());
+    topPanel.setBorder(UIFactory.DIALOG_PANEL_BORDER);
+    topPanel.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
+    Insets insets = UIFactory.getCurrentStepPanelInsets();
+
+    gbc.weighty = 0.0;
+    insets.bottom = 0;
+    gbc.insets = insets;
+    topPanel.add(createTitlePanel(), gbc);
+    gbc.insets.top = UIFactory.TOP_INSET_INSTRUCTIONS_SUBPANEL;
+    topPanel.add(createInstructionsPane(), gbc);
+    gbc.insets.top = UIFactory.TOP_INSET_INPUT_SUBPANEL;
+    gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL;
+    topPanel.add(createInputPanel(), gbc);
+    gbc.weighty = 1.0;
+    gbc.insets = UIFactory.getEmptyInsets();
+    topPanel.add(Box.createVerticalGlue(), gbc);
+    contentPanel.add(topPanel, gbc);
+    gbc.weighty = 0.0;
+    gbc.insets = UIFactory.getButtonsPanelInsets();
+    contentPanel.add(createButtonsPanel(), gbc);
+
+    return contentPanel;
+  }
+
+  /**
+   * Creates and returns the title sub panel.
+   * @return the title sub panel.
+   */
+  private Component createTitlePanel()
+  {
+    JPanel titlePanel = new JPanel(new GridBagLayout());
+    GridBagConstraints gbc = new GridBagConstraints();
+    titlePanel.setOpaque(false);
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.weightx = 0.0;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+
+    String title = getMsg("security-options-title");
+    JLabel l =
+        UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, title,
+            UIFactory.TextStyle.TITLE);
+    l.setOpaque(false);
+    titlePanel.add(l, gbc);
+
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets.left = 0;
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    titlePanel.add(Box.createHorizontalGlue(), gbc);
+
+    return titlePanel;
+  }
+
+  /**
+   * Creates and returns the instructions sub panel.
+   * @return the instructions sub panel.
+   */
+  private Component createInstructionsPane()
+  {
+    String instructions = getMsg("security-options-instructions");
+
+    JTextComponent instructionsPane =
+      UIFactory.makeHtmlPane(instructions, UIFactory.INSTRUCTIONS_FONT);
+    instructionsPane.setOpaque(false);
+    instructionsPane.setEditable(false);
+
+    return instructionsPane;
+  }
+
+  /**
+   * Creates and returns the input sub panel: the panel with all the widgets
+   * that are used to define the security options.
+   * @return the input sub panel.
+   */
+  private Component createInputPanel()
+  {
+    JPanel inputPanel = new JPanel(new GridBagLayout());
+    inputPanel.setOpaque(false);
+
+    ActionListener l = new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        updateEnablingState();
+      }
+    };
+
+    cbEnableSSL = UIFactory.makeJCheckBox(getMsg("enable-ssl-label"),
+        getMsg("enable-ssl-tooltip"), UIFactory.TextStyle.PRIMARY_FIELD_VALID);
+    cbEnableSSL.addActionListener(l);
+    cbEnableSSL.setOpaque(false);
+    String sPort = "";
+    int port = securityOptions.getSslPort();
+    if (port > 0)
+    {
+      sPort = String.valueOf(port);
+    }
+    tfPort = UIFactory.makeJTextField(sPort,
+        getMsg("ssl-port-textfield-tooltip"), UIFactory.PORT_FIELD_SIZE,
+        UIFactory.TextStyle.TEXTFIELD);
+    cbEnableStartTLS = UIFactory.makeJCheckBox(getMsg("enable-starttls-label"),
+        getMsg("enable-starttls-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    cbEnableStartTLS.addActionListener(l);
+    cbEnableStartTLS.setOpaque(false);
+    rbUseSelfSignedCertificate = UIFactory.makeJRadioButton(
+        getMsg("use-self-signed-label"),
+        getMsg("use-self-signed-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbUseSelfSignedCertificate.setOpaque(false);
+    rbUseSelfSignedCertificate.addActionListener(l);
+    lSelfSignedName = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("self-signed-certificate-name-label"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    lSelfSignedName.setOpaque(false);
+    String selfSignedName = securityOptions.getSelfSignedCertificateName();
+    tfSelfSignedName = UIFactory.makeJTextField(selfSignedName,
+        getMsg("self-signed-certificate-name-tooltip"),
+        UIFactory.HOST_FIELD_SIZE, UIFactory.TextStyle.TEXTFIELD);
+    lSelfSignedName.setLabelFor(tfSelfSignedName);
+    rbUseExistingCertificate = UIFactory.makeJRadioButton(
+        getMsg("use-existing-certificate-label"),
+        getMsg("use-existing-certificate-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbUseExistingCertificate.setOpaque(false);
+    rbUseExistingCertificate.addActionListener(l);
+    ButtonGroup group1 = new ButtonGroup();
+    group1.add(rbUseSelfSignedCertificate);
+    group1.add(rbUseExistingCertificate);
+
+    lKeystoreType = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("keystore-type-label"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    lKeystoreType.setOpaque(false);
+    rbJKS = UIFactory.makeJRadioButton(
+        getMsg("jks-certificate-label"),
+        getMsg("jks-certificate-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbJKS.setOpaque(false);
+    rbJKS.addActionListener(l);
+    rbPKCS11 = UIFactory.makeJRadioButton(
+        getMsg("pkcs11-certificate-label"),
+        getMsg("pkcs11-certificate-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbPKCS11.setOpaque(false);
+    rbPKCS11.addActionListener(l);
+    rbPKCS12 = UIFactory.makeJRadioButton(
+        getMsg("pkcs12-certificate-label"),
+        getMsg("pkcs12-certificate-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbPKCS12.setOpaque(false);
+    rbPKCS12.addActionListener(l);
+    ButtonGroup group2 = new ButtonGroup();
+    group2.add(rbJKS);
+    group2.add(rbPKCS11);
+    group2.add(rbPKCS12);
+    lKeystoreType.setLabelFor(rbJKS);
+
+    lKeystorePath = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("keystore-path-label"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    lKeystorePath.setOpaque(false);
+    tfKeystorePath = UIFactory.makeJTextField("",
+        getMsg("keystore-path-tooltip"),
+        UIFactory.HOST_FIELD_SIZE, UIFactory.TextStyle.TEXTFIELD);
+    lKeystorePath.setLabelFor(tfKeystorePath);
+    browseButton =
+      UIFactory.makeJButton(getMsg("browse-button-label"),
+          getMsg("browse-button-tooltip"));
+
+    BrowseActionListener browseListener =
+      new BrowseActionListener(tfKeystorePath,
+          BrowseActionListener.BrowseType.GENERIC_FILE,
+          this);
+    browseButton.addActionListener(browseListener);
+
+    lKeystorePwd = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("keystore-pwd-label"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    lKeystorePwd.setOpaque(false);
+    tfKeystorePwd = UIFactory.makeJPasswordField("",
+        getMsg("keystore-pwd-tooltip"),
+        UIFactory.PASSWORD_FIELD_SIZE, UIFactory.TextStyle.PASSWORD_FIELD);
+    lKeystorePwd.setLabelFor(tfKeystorePwd);
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.anchor = GridBagConstraints.WEST;
+    gbc.weightx = 0.0;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    inputPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("ssl-access-label"), UIFactory.TextStyle.PRIMARY_FIELD_VALID),
+        gbc);
+
+    JPanel auxPanel = new JPanel(new GridBagLayout());
+    auxPanel.setOpaque(false);
+    gbc.gridwidth = 4;
+    gbc.fill = GridBagConstraints.NONE;
+    auxPanel.add(cbEnableSSL, gbc);
+    gbc.gridwidth--;
+    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+    auxPanel.add(tfPort, gbc);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    auxPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getPortHelpMessage(), UIFactory.TextStyle.SECONDARY_FIELD_VALID), gbc);
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.weightx = 1.0;
+    auxPanel.add(Box.createHorizontalGlue(), gbc);
+
+    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
+    gbc.weightx = 1.0;
+    inputPanel.add(auxPanel, gbc);
+
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.weightx = 0.0;
+    inputPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("starttls-access-label"),
+        UIFactory.TextStyle.PRIMARY_FIELD_VALID),
+        gbc);
+    auxPanel = new JPanel(new GridBagLayout());
+    auxPanel.setOpaque(false);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.insets = UIFactory.getEmptyInsets();
+    auxPanel.add(cbEnableStartTLS, gbc);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    auxPanel.add(Box.createHorizontalGlue(), gbc);
+    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    inputPanel.add(auxPanel, gbc);
+
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.weightx = 0.0;
+    JLabel lCertificate = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("certificate-label"), UIFactory.TextStyle.PRIMARY_FIELD_VALID);
+    int additionalInset = Math.abs(lCertificate.getPreferredSize().height -
+        rbUseSelfSignedCertificate.getPreferredSize().height) / 2;
+    gbc.insets.top += additionalInset;
+    inputPanel.add(lCertificate, gbc);
+    auxPanel = new JPanel(new GridBagLayout());
+    auxPanel.setOpaque(false);
+    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.weightx = 1.0;
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    inputPanel.add(auxPanel, gbc);
+
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.anchor = GridBagConstraints.WEST;
+    JPanel aux2Panel = new JPanel(new GridBagLayout());
+    aux2Panel.setOpaque(false);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    aux2Panel.add(rbUseSelfSignedCertificate, gbc);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    aux2Panel.add(Box.createHorizontalGlue(), gbc);
+    auxPanel.add(aux2Panel, gbc);
+
+    aux2Panel = new JPanel(new GridBagLayout());
+    aux2Panel.setOpaque(false);
+    gbc.weightx = 0.0;
+    gbc.gridwidth = 3;
+    aux2Panel.add(lSelfSignedName, gbc);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+    aux2Panel.add(tfSelfSignedName, gbc);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets.left = 0;
+    aux2Panel.add(Box.createHorizontalGlue(), gbc);
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
+    auxPanel.add(aux2Panel, gbc);
+
+    aux2Panel = new JPanel(new GridBagLayout());
+    aux2Panel.setOpaque(false);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.weightx = 0.0;
+    aux2Panel.add(rbUseExistingCertificate, gbc);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    aux2Panel.add(Box.createHorizontalGlue(), gbc);
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    auxPanel.add(aux2Panel, gbc);
+
+    additionalInset = Math.abs(lKeystoreType.getPreferredSize().height -
+        rbJKS.getPreferredSize().height) / 2;
+    aux2Panel = new JPanel(new GridBagLayout());
+    aux2Panel.setOpaque(false);
+    gbc.insets.top -= additionalInset;
+    gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
+    auxPanel.add(aux2Panel, gbc);
+
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.weightx = 0.0;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.insets.top = additionalInset;
+    aux2Panel.add(lKeystoreType, gbc);
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets.top = 0;
+    aux2Panel.add(rbJKS, gbc);
+
+    gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    aux2Panel.add(Box.createHorizontalGlue(), gbc);
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    aux2Panel.add(rbPKCS12, gbc);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    aux2Panel.add(Box.createHorizontalGlue(), gbc);
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    aux2Panel.add(rbPKCS11, gbc);
+
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.insets.left = 0;
+    gbc.weightx = 0.0;
+    gbc.anchor = GridBagConstraints.WEST;
+    aux2Panel.add(lKeystorePath, gbc);
+    JPanel aux3Panel = new JPanel(new GridBagLayout());
+    aux3Panel.setOpaque(false);
+    gbc.weightx = 1.0;
+    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    aux2Panel.add(aux3Panel, gbc);
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    aux3Panel.add(tfKeystorePath, gbc);
+    gbc.insets.left = UIFactory.LEFT_INSET_BROWSE;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.weightx = 0.0;
+    aux3Panel.add(browseButton, gbc);
+
+    gbc.insets.left = 0;
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.weightx = 0.0;
+    gbc.anchor = GridBagConstraints.WEST;
+    aux2Panel.add(lKeystorePwd, gbc);
+    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.fill = GridBagConstraints.NONE;
+    aux2Panel.add(tfKeystorePwd, gbc);
+
+    return inputPanel;
+  }
+
+  /**
+   * Creates and returns the buttons OK/CANCEL sub panel.
+   * @return the buttons OK/CANCEL sub panel.
+   */
+  private Component createButtonsPanel()
+  {
+    JPanel buttonsPanel = new JPanel(new GridBagLayout());
+    buttonsPanel.setOpaque(false);
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.gridwidth = 4;
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.insets.left = UIFactory.getCurrentStepPanelInsets().left;
+    buttonsPanel.add(UIFactory.makeJLabel(UIFactory.IconType.OPENDS_SMALL,
+        null, UIFactory.TextStyle.NO_STYLE), gbc);
+    gbc.weightx = 1.0;
+    gbc.gridwidth--;
+    gbc.insets.left = 0;
+    buttonsPanel.add(Box.createHorizontalGlue(), gbc);
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.weightx = 0.0;
+    okButton =
+      UIFactory.makeJButton(getMsg("ok-button-label"),
+          getMsg("security-options-ok-button-tooltip"));
+    buttonsPanel.add(okButton, gbc);
+    okButton.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        okClicked();
+      }
+    });
+
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
+    cancelButton =
+      UIFactory.makeJButton(getMsg("cancel-button-label"),
+          getMsg("security-options-cancel-button-tooltip"));
+    buttonsPanel.add(cancelButton, gbc);
+    cancelButton.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        cancelClicked();
+      }
+    });
+
+    return buttonsPanel;
+  }
+
+  /**
+   * Method called when user clicks on cancel.
+   *
+   */
+  private void cancelClicked()
+  {
+    isCancelled = true;
+    dispose();
+  }
+
+  /**
+   * Method called when user clicks on OK.
+   *
+   */
+  private void okClicked()
+  {
+    BackgroundTask worker = new BackgroundTask()
+    {
+      public Object processBackgroundTask()
+      {
+        ArrayList<String> errorMsgs = new ArrayList<String>();
+
+        errorMsgs.addAll(checkPort());
+
+        errorMsgs.addAll(checkSelfSigned());
+
+        errorMsgs.addAll(checkKeystore());
+
+        return errorMsgs;
+      }
+
+      public void backgroundTaskCompleted(Object returnValue,
+          Throwable throwable)
+      {
+        if (throwable != null)
+        {
+          // Bug
+          throwable.printStackTrace();
+          displayError(
+              Utils.getThrowableMsg(getI18n(), "bug-msg", null, throwable),
+              getMsg("error-title"));
+          cancelButton.setEnabled(true);
+          okButton.setEnabled(true);
+        }
+        else
+        {
+          cancelButton.setEnabled(true);
+          okButton.setEnabled(true);
+          ArrayList ar = (ArrayList)returnValue;
+
+          if (ar.size() > 0)
+          {
+            ArrayList<String> errorMsgs = new ArrayList<String>();
+            for (Object o: ar)
+            {
+              errorMsgs.add((String)o);
+            }
+            displayError(Utils.getStringFromCollection(errorMsgs, "\n"),
+                getMsg("error-title"));
+          }
+          else
+          {
+            if (rbUseExistingCertificate.isSelected() &&
+                (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected()))
+            {
+              if (aliases.length > 1)
+              {
+                if (aliasDlg == null)
+                {
+                  aliasDlg = new SelectAliasDialog(SecurityOptionsDialog.this);
+                }
+                aliasDlg.display(aliases);
+
+                if (!aliasDlg.isCancelled())
+                {
+                  selectedAlias = aliasDlg.getSelectedAlias();
+                  isCancelled = false;
+                  dispose();
+                }
+              }
+              else
+              {
+                selectedAlias = aliases[0];
+                isCancelled = false;
+                dispose();
+              }
+            }
+            else
+            {
+              isCancelled = false;
+              dispose();
+            }
+          }
+        }
+      }
+    };
+    cancelButton.setEnabled(false);
+    okButton.setEnabled(false);
+    worker.startBackgroundTask();
+  }
+
+  /**
+   * Displays an error message dialog.
+   *
+   * @param msg
+   *          the error message.
+   * @param title
+   *          the title for the dialog.
+   */
+  private void displayError(String msg, String title)
+  {
+    Utils.displayError(this, msg, title);
+    toFront();
+  }
+
+  /**
+   * Updates the widgets on the dialog with the contents of the securityOptions
+   * object.
+   *
+   */
+  private void updateContents()
+  {
+    cbEnableSSL.setSelected(securityOptions.getEnableSSL());
+    cbEnableStartTLS.setSelected(securityOptions.getEnableStartTLS());
+    if (securityOptions.getEnableSSL())
+    {
+      int port = securityOptions.getSslPort();
+      if (port > 0)
+      {
+        tfPort.setText(String.valueOf(port));
+      }
+    }
+
+    switch (securityOptions.getCertificateType())
+    {
+    case NO_CERTIFICATE:
+      // Nothing else to do
+      break;
+
+    case SELF_SIGNED_CERTIFICATE:
+      rbUseSelfSignedCertificate.setSelected(true);
+      tfSelfSignedName.setText(securityOptions.getSelfSignedCertificateName());
+      break;
+
+    case JKS:
+      rbUseExistingCertificate.setSelected(true);
+      rbJKS.setSelected(true);
+      tfKeystorePath.setText(securityOptions.getKeystorePath());
+      tfKeystorePwd.setText(securityOptions.getKeystorePassword());
+      break;
+
+    case PKCS11:
+      rbUseExistingCertificate.setSelected(true);
+      rbPKCS11.setSelected(true);
+      tfKeystorePwd.setText(securityOptions.getKeystorePassword());
+      break;
+
+    case PKCS12:
+      rbUseExistingCertificate.setSelected(true);
+      rbPKCS12.setSelected(true);
+      tfKeystorePath.setText(securityOptions.getKeystorePath());
+      tfKeystorePwd.setText(securityOptions.getKeystorePassword());
+      break;
+
+    default:
+      throw new IllegalStateException("Unknown certificate type.");
+    }
+
+    updateEnablingState();
+  }
+
+  /**
+   * Enables/disables and makes visible/invisible the objects according to what
+   * the user selected.
+   */
+  private void updateEnablingState()
+  {
+    boolean enableSSL = cbEnableSSL.isSelected();
+    boolean enableStartTLS = cbEnableStartTLS.isSelected();
+
+    boolean useSSL = enableSSL || enableStartTLS;
+
+    if (useSSL && !rbUseSelfSignedCertificate.isSelected() &&
+        !rbUseExistingCertificate.isSelected())
+    {
+      rbUseSelfSignedCertificate.setSelected(true);
+    }
+
+    if (useSSL && rbUseExistingCertificate.isSelected() &&
+        !rbJKS.isSelected() && !rbPKCS11.isSelected() && !rbPKCS12.isSelected())
+    {
+      rbJKS.setSelected(true);
+    }
+    tfPort.setEnabled(enableSSL);
+
+    rbUseSelfSignedCertificate.setEnabled(useSSL);
+    lSelfSignedName.setEnabled(
+        rbUseSelfSignedCertificate.isSelected() && useSSL);
+    tfSelfSignedName.setEnabled(
+        rbUseSelfSignedCertificate.isSelected() && useSSL);
+
+    rbUseExistingCertificate.setEnabled(useSSL);
+    lKeystoreType.setEnabled(
+        rbUseExistingCertificate.isSelected() && useSSL);
+    rbJKS.setEnabled(rbUseExistingCertificate.isSelected() && useSSL);
+    rbPKCS11.setEnabled(rbUseExistingCertificate.isSelected() && useSSL);
+    rbPKCS12.setEnabled(rbUseExistingCertificate.isSelected() && useSSL);
+
+    lKeystorePath.setEnabled(
+        rbUseExistingCertificate.isSelected() && useSSL);
+    tfKeystorePath.setEnabled(
+        rbUseExistingCertificate.isSelected() && useSSL);
+    browseButton.setEnabled(rbUseExistingCertificate.isSelected() && useSSL);
+    lKeystorePwd.setEnabled(
+        rbUseExistingCertificate.isSelected() && useSSL);
+    tfKeystorePwd.setEnabled(
+        rbUseExistingCertificate.isSelected() && useSSL);
+
+    lKeystorePath.setVisible(!rbPKCS11.isSelected());
+    tfKeystorePath.setVisible(!rbPKCS11.isSelected());
+    browseButton.setVisible(!rbPKCS11.isSelected());
+  }
+
+  /**
+   * Returns the port help message that we display when we cannot use the
+   * default port (636).
+   * @return the port help message that we display when we cannot use the
+   * default port (636).
+   */
+  private String getPortHelpMessage()
+  {
+    String s = "";
+    if (securityOptions.getSslPort() != DEFAULT_PORT)
+    {
+      s = getMsg("cannot-use-default-secure-port");
+    }
+    return s;
+  }
+
+  /* The following three methods are just commodity methods to retrieve
+   * localized messages */
+  private String getMsg(String key)
+  {
+    return getI18n().getMsg(key);
+  }
+
+  private String getMsg(String key, String[] args)
+  {
+    return getI18n().getMsg(key, args);
+  }
+
+  private ResourceProvider getI18n()
+  {
+    return ResourceProvider.getInstance();
+  }
+
+  /**
+   * Checks the port.
+   * @return the error messages found while checking the port.
+   */
+  private ArrayList<String> checkPort()
+  {
+    ArrayList<String> errorMsgs = new ArrayList<String>();
+
+    if (cbEnableSSL.isSelected())
+    {
+      /* Check the port. */
+      String sPort = tfPort.getText();
+      int port = -1;
+      try
+      {
+        port = Integer.parseInt(sPort);
+        if ((port < Installer.MIN_PORT_VALUE) ||
+            (port > Installer.MAX_PORT_VALUE))
+        {
+          String[] args =
+            { String.valueOf(Installer.MIN_PORT_VALUE),
+              String.valueOf(Installer.MAX_PORT_VALUE) };
+          errorMsgs.add(getMsg("invalid-secure-port-value-range", args));
+
+        }
+        else if (!Utils.canUseAsPort(port))
+        {
+          if (Utils.isPriviledgedPort(port))
+          {
+            errorMsgs.add(getMsg("cannot-bind-priviledged-port", new String[]
+              { String.valueOf(port) }));
+          }
+          else
+          {
+            errorMsgs.add(getMsg("cannot-bind-port", new String[]
+              { String.valueOf(port) }));
+          }
+
+        }
+
+      }
+      catch (NumberFormatException nfe)
+      {
+        String[] args =
+          { String.valueOf(Installer.MIN_PORT_VALUE),
+            String.valueOf(Installer.MAX_PORT_VALUE) };
+        errorMsgs.add(getMsg("invalid-secure-port-value-range", args));
+      }
+    }
+    setValidLater(cbEnableSSL, errorMsgs.size() == 0);
+    return errorMsgs;
+  }
+
+  /**
+   * Checks the self-signed certificate parameters.
+   * @return the error messages found while checking self-signed certificate
+   * parameters.
+   */
+  private ArrayList<String> checkSelfSigned()
+  {
+    ArrayList<String> errorMsgs = new ArrayList<String>();
+
+    if (rbUseSelfSignedCertificate.isSelected() &&
+        (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected()))
+    {
+      String name = tfSelfSignedName.getText();
+      if ((name != null) && (name.length() > 0))
+      {
+        /* TODO: We might try to do something to check if the user provided a
+         * valid host name, but we cannot guarantee that the check will be valid
+         * AND we might want to allow the user to use a common name for the
+         * certificate that is not the host name.
+         */
+      }
+      else
+      {
+        errorMsgs.add(getMsg("no-self-signed-cert-name-provided"));
+      }
+    }
+
+    setValidLater(lSelfSignedName, errorMsgs.size() == 0);
+
+    return errorMsgs;
+  }
+
+  /**
+   * Checks the existing keystore parameters.
+   * @return the error messages found while checking existing keystore
+   * parameters.
+   */
+  private ArrayList<String> checkKeystore()
+  {
+    ArrayList<String> errorMsgs = new ArrayList<String>();
+
+    boolean pathValid = true;
+    boolean pwdValid = true;
+
+    if (rbUseExistingCertificate.isSelected() &&
+        (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected()))
+    {
+      String path = tfKeystorePath.getText();
+      if (rbJKS.isSelected() || rbPKCS12.isSelected())
+      {
+        /* Check the path */
+        if ((path == null) || (path.length() == 0))
+        {
+          errorMsgs.add(getMsg("keystore-path-not-provided"));
+        }
+        else
+        {
+          File f = new File(path);
+          if (!f.exists())
+          {
+            errorMsgs.add(getMsg("keystore-path-does-not-exist"));
+          }
+          else if (!f.isFile())
+          {
+            errorMsgs.add(getMsg("keystore-path-not-a-file"));
+          }
+        }
+
+        pathValid = errorMsgs.size() == 0;
+      }
+
+      /* Check the password */
+      String pwd = String.valueOf(tfKeystorePwd.getPassword());
+      if ((pwd == null) || (pwd.length() == 0))
+      {
+        errorMsgs.add(getMsg("keystore-pwd-empty"));
+        pwdValid = false;
+      }
+
+      if (pathValid && pwdValid)
+      {
+        // TODO: put the password in a temporary file to do the checks.
+        try
+        {
+          CertificateManager certManager;
+          if (rbJKS.isSelected())
+          {
+            certManager = new CertificateManager(
+                path,
+                CertificateManager.KEY_STORE_TYPE_JKS,
+                pwd);
+          }
+          else if (rbPKCS12.isSelected())
+          {
+            certManager = new CertificateManager(
+                path,
+                CertificateManager.KEY_STORE_TYPE_PKCS12,
+                pwd);
+          }
+          else if (rbPKCS11.isSelected())
+          {
+            certManager = new CertificateManager(
+                CertificateManager.KEY_STORE_PATH_PKCS11,
+                CertificateManager.KEY_STORE_TYPE_PKCS11,
+                pwd);
+          }
+          else
+          {
+            throw new IllegalStateException("No keystore type selected.");
+          }
+          aliases = certManager.getCertificateAliases();
+          if ((aliases == null) || (aliases.length == 0))
+          {
+            // Could not retrieve any certificate
+            if (rbPKCS11.isSelected())
+            {
+              errorMsgs.add(getMsg("pkcs11-keystore-does-not-exist"));
+            }
+            else
+            {
+              if (rbJKS.isSelected())
+              {
+                errorMsgs.add(getMsg("jks-keystore-does-not-exist"));
+              }
+              else
+              {
+                errorMsgs.add(getMsg("pkcs12-keystore-does-not-exist"));
+              }
+              pathValid = false;
+            }
+          }
+        }
+        catch (KeyStoreException ke)
+        {
+          pwdValid = false;
+          if (!rbPKCS11.isSelected())
+          {
+            pathValid = false;
+          }
+          // Could not access to the keystore: because the password is no good,
+          // because the provided file is not a valid keystore, etc.
+          if (rbPKCS11.isSelected())
+          {
+            errorMsgs.add(getMsg("error-accessing-pkcs11-keystore"));
+          }
+          else
+          {
+            if (rbJKS.isSelected())
+            {
+              errorMsgs.add(getMsg("error-accessing-jks-keystore"));
+            }
+            else
+            {
+              errorMsgs.add(getMsg("error-accessing-pkcs12-keystore"));
+            }
+            pathValid = false;
+          }
+        }
+      }
+    }
+
+    setValidLater(lKeystorePath, pathValid);
+    setValidLater(lKeystorePwd, pwdValid);
+
+    return errorMsgs;
+  }
+
+  /**
+   * Method that updates the text style of a provided component by calling
+   * SwingUtilities.invokeLater.  This method is aimed to be called outside
+   * the event thread (calling it from the event thread will also work though).
+   * @param comp the component to be updated.
+   * @param valid whether to use a TextStyle to mark the component as valid
+   * or as invalid.
+   */
+  private void setValidLater(final JComponent comp, final boolean valid)
+  {
+    SwingUtilities.invokeLater(new Runnable()
+    {
+      public void run()
+      {
+        UIFactory.setTextStyle(comp,
+            valid ? UIFactory.TextStyle.SECONDARY_FIELD_VALID :
+              UIFactory.TextStyle.SECONDARY_FIELD_INVALID);
+      }
+    });
+  }
+
+  /**
+   * Method written for testing purposes.
+   * @param args the arguments to be passed to the test program.
+   */
+  public static void main(String[] args)
+  {
+    try
+    {
+      // UIFactory.initialize();
+      SecurityOptionsDialog dlg = new SecurityOptionsDialog(new JFrame(),
+          SecurityOptions.createNoCertificateOptions());
+      dlg.pack();
+      dlg.setVisible(true);
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java
new file mode 100644
index 0000000..426fea9
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java
@@ -0,0 +1,275 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.quicksetup.ui;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.TreeSet;
+
+import javax.swing.Box;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.text.JTextComponent;
+
+import org.opends.quicksetup.event.MinimumSizeComponentListener;
+import org.opends.quicksetup.i18n.ResourceProvider;
+import org.opends.quicksetup.util.Utils;
+
+/**
+ * This class is a dialog that appears when the user must choose the alias to
+ * be used from a certificate keystore.
+ */
+public class SelectAliasDialog extends JDialog
+{
+  private JButton okButton;
+  private JComboBox comboAliases;
+  private boolean isCancelled;
+
+  private static final long serialVersionUID = -8140704273612764046L;
+
+  /**
+   * Constructor of the SelectAliasDialog.
+   * @param parent the parent frame for this dialog.
+   */
+  public SelectAliasDialog(JDialog parent)
+  {
+    super(parent);
+    setTitle(getMsg("select-alias-title"));
+    getContentPane().add(createPanel());
+    pack();
+    int minWidth = (int) getPreferredSize().getWidth();
+    int minHeight = (int) getPreferredSize().getHeight();
+    addComponentListener(new MinimumSizeComponentListener(this, minWidth,
+        minHeight));
+    getRootPane().setDefaultButton(okButton);
+
+    addWindowListener(new WindowAdapter()
+    {
+      public void windowClosing(WindowEvent e)
+      {
+        cancelClicked();
+      }
+    });
+    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+
+    Utils.centerOnComponent(this, parent);
+    setModal(true);
+  }
+
+  /**
+   * Displays this dialog with the provided aliases.
+   *
+   * @param aliases the aliases to display.
+   */
+  public void display(String[] aliases)
+  {
+    if ((aliases == null) || (aliases.length ==0))
+    {
+      throw new IllegalArgumentException(
+          "The provided aliases are null or empty.");
+    }
+    isCancelled = true;
+    TreeSet<String> s = new TreeSet<String>();
+    for (int i=0; i<aliases.length; i++)
+    {
+      s.add(aliases[i]);
+    }
+    String[] orderedAliases = new String[s.size()];
+    s.toArray(orderedAliases);
+    comboAliases.setModel(new DefaultComboBoxModel(orderedAliases));
+    comboAliases.setSelectedIndex(0);
+    setVisible(true);
+  }
+
+  /**
+   * Returns <CODE>true</CODE> if the user clicked on cancel and
+   * <CODE>false</CODE> otherwise.
+   * @return <CODE>true</CODE> if the user clicked on cancel and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean isCancelled()
+  {
+    return isCancelled;
+  }
+
+  /**
+   * Returns the selected certificate alias.
+   * @return the selected certificate alias.
+   */
+  public String getSelectedAlias()
+  {
+    return (String) comboAliases.getSelectedItem();
+  }
+
+  /* The following three methods are just commodity methods to retrieve
+   * localized messages */
+  private String getMsg(String key)
+  {
+    return getI18n().getMsg(key);
+  }
+
+  private ResourceProvider getI18n()
+  {
+    return ResourceProvider.getInstance();
+  }
+
+  /**
+   * Creates and returns the panel of the dialog.
+   * @return the panel of the dialog.
+   */
+  private JPanel createPanel()
+  {
+    JPanel p1 = new JPanel(new GridBagLayout());
+    p1.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
+    p1.setBorder(UIFactory.DIALOG_PANEL_BORDER);
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+
+    Insets currentStepInsets = UIFactory.getCurrentStepPanelInsets();
+    gbc.insets.top = currentStepInsets.top;
+    gbc.insets.left = currentStepInsets.left;
+
+    p1.add(UIFactory.makeJLabel(UIFactory.IconType.INFORMATION_LARGE, null,
+        UIFactory.TextStyle.NO_STYLE), gbc);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+    gbc.fill = GridBagConstraints.BOTH;
+    String msg = getMsg("select-alias-msg");
+    JTextComponent tf = UIFactory.makeHtmlPane(msg,
+            UIFactory.INSTRUCTIONS_FONT);
+    tf.setOpaque(false);
+    tf.setEditable(false);
+    p1.add(tf, gbc);
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.insets.left = currentStepInsets.left;
+    gbc.insets.right = currentStepInsets.right;
+    gbc.insets.bottom = currentStepInsets.bottom;
+    comboAliases = new JComboBox();
+    comboAliases.setPrototypeDisplayValue("The prototype alias name");
+    gbc.fill = GridBagConstraints.NONE;
+    p1.add(comboAliases, gbc);
+
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.VERTICAL;
+    p1.add(Box.createVerticalGlue(), gbc);
+
+    JPanel p2 = new JPanel(new GridBagLayout());
+    p2.setOpaque(false);
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.weightx = 1.0;
+    gbc.gridwidth = 3;
+    p2.add(Box.createHorizontalGlue(), gbc);
+    okButton = UIFactory.makeJButton(getMsg("ok-button-label"),
+          getMsg("select-alias-ok-button-tooltip"));
+    okButton.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        okClicked();
+      }
+    });
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.weightx = 0.0;
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+    p2.add(okButton, gbc);
+    JButton cancelButton = UIFactory.makeJButton(getMsg("cancel-button-label"),
+            getMsg("select-alias-cancel-button-tooltip"));
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
+    p2.add(cancelButton, gbc);
+    cancelButton.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        cancelClicked();
+      }
+    });
+
+    JPanel p = new JPanel(new GridBagLayout());
+    p.setBackground(UIFactory.DEFAULT_BACKGROUND);
+    gbc.insets = UIFactory.getEmptyInsets();
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.weightx = 1.0;
+    gbc.weighty = 1.0;
+    p.add(p1, gbc);
+    gbc.weighty = 0.0;
+    gbc.insets = UIFactory.getButtonsPanelInsets();
+    p.add(p2, gbc);
+    return p;
+  }
+
+  /**
+   * Method called when user clicks on cancel.
+   *
+   */
+  private void cancelClicked()
+  {
+    isCancelled = true;
+    dispose();
+  }
+
+  /**
+   * Method called when user clicks on OK.
+   *
+   */
+  private void okClicked()
+  {
+    isCancelled = false;
+    dispose();
+  }
+
+  /**
+   * Method written for testing purposes.
+   * @param args the arguments to be passed to the test program.
+   */
+  public static void main(String[] args)
+  {
+    try
+    {
+      // UIFactory.initialize();
+      SelectAliasDialog dlg =
+          new SelectAliasDialog(new JDialog());
+      dlg.display(new String[] {"test1", "test2"});
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
index 0bdbf53..8681077 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
@@ -30,6 +30,8 @@
 import java.awt.Component;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.io.File;
@@ -37,12 +39,14 @@
 
 import javax.swing.Box;
 import javax.swing.JButton;
+import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.text.JTextComponent;
 
 import org.opends.quicksetup.event.BrowseActionListener;
 import org.opends.quicksetup.util.Utils;
+import org.opends.quicksetup.SecurityOptions;
 import org.opends.quicksetup.UserData;
 
 /**
@@ -56,10 +60,18 @@
 
   private Component lastFocusComponent;
 
+  private JLabel lSecurity;
+
+  private JButton secureAccessButton;
+
   private JButton browseButton;
 
   private boolean displayServerLocation;
 
+  private boolean canUpdateSecurity;
+
+  private SecurityOptions securityOptions;
+
   private HashMap<FieldName, JLabel> hmLabels =
       new HashMap<FieldName, JLabel>();
 
@@ -72,6 +84,8 @@
 
   private JLabel lServerLocation;
 
+  private SecurityOptionsDialog dlg;
+
   private static final long serialVersionUID = -15911406930993035L;
 
   /**
@@ -84,6 +98,9 @@
     super(application);
     this.defaultUserData = application.getUserData();
     this.displayServerLocation = isWebStart();
+    canUpdateSecurity =
+      org.opends.server.util.CertificateManager.mayUseCertificateManager();
+    securityOptions = defaultUserData.getSecurityOptions();
     populateLabelAndFieldMaps();
     addFocusListeners();
   }
@@ -114,7 +131,12 @@
         }
       }
 
-    } else
+    }
+    else if (fieldName == FieldName.SECURITY_OPTIONS)
+    {
+      value = securityOptions;
+    }
+    else
     {
       JTextComponent field = getField(fieldName);
       if (field != null)
@@ -157,9 +179,13 @@
     GridBagConstraints gbc = new GridBagConstraints();
 
     FieldName[] fieldNames =
-          { FieldName.SERVER_PORT, FieldName.DIRECTORY_MANAGER_DN,
-              FieldName.DIRECTORY_MANAGER_PWD,
-              FieldName.DIRECTORY_MANAGER_PWD_CONFIRM };
+    {
+        FieldName.SERVER_PORT,
+        FieldName.SECURITY_OPTIONS,
+        FieldName.DIRECTORY_MANAGER_DN,
+        FieldName.DIRECTORY_MANAGER_PWD,
+        FieldName.DIRECTORY_MANAGER_PWD_CONFIRM
+    };
 
     JPanel auxPanel;
     // Add the server location widgets
@@ -211,7 +237,21 @@
       gbc.weightx = 0.0;
       gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
       gbc.insets.left = 0;
-      gbc.anchor = GridBagConstraints.WEST;
+      boolean isSecurityField = fieldName == FieldName.SECURITY_OPTIONS;
+
+      int securityInsetsTop = Math.abs(
+          getLDAPSecureAccessButton().getPreferredSize().height -
+          getLabel(fieldName).getPreferredSize().height) / 2;
+
+      if (isSecurityField)
+      {
+        gbc.anchor = GridBagConstraints.NORTHWEST;
+        gbc.insets.top += securityInsetsTop;
+      }
+      else
+      {
+        gbc.anchor = GridBagConstraints.WEST;
+      }
       panel.add(getLabel(fieldName), gbc);
 
       auxPanel = new JPanel(new GridBagLayout());
@@ -221,18 +261,41 @@
       gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
       gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
       gbc.gridwidth = GridBagConstraints.REMAINDER;
+
       panel.add(auxPanel, gbc);
 
       boolean isPortField = fieldName == FieldName.SERVER_PORT;
       gbc.insets = UIFactory.getEmptyInsets();
-      if (isPortField) {
+      if (isPortField || (isSecurityField && canUpdateSecurity))
+      {
         gbc.gridwidth = 3;
-      } else {
+      }
+      else
+      {
         gbc.gridwidth = GridBagConstraints.RELATIVE;
       }
       gbc.weightx = 0.0;
-      auxPanel.add(getField(fieldName), gbc);
-      if (isPortField) {
+      if (isSecurityField)
+      {
+        gbc.insets.top = securityInsetsTop;
+        if (canUpdateSecurity)
+        {
+          auxPanel.add(lSecurity, gbc);
+        }
+        else
+        {
+          auxPanel.add(UIFactory.makeJLabel(UIFactory.IconType.WARNING,
+              getMsg("cannot-update-security-warning"),
+              UIFactory.TextStyle.SECONDARY_FIELD_VALID), gbc);
+        }
+      }
+      else
+      {
+        auxPanel.add(getField(fieldName), gbc);
+      }
+
+      if (isPortField)
+      {
         JLabel l =
                 UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
                         getPortHelpMessage(),
@@ -241,9 +304,17 @@
         gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
         auxPanel.add(l, gbc);
       }
-
+      else if (isSecurityField && canUpdateSecurity)
+      {
+        gbc.gridwidth = GridBagConstraints.RELATIVE;
+        gbc.insets.left = UIFactory.LEFT_INSET_BROWSE;
+        gbc.anchor = GridBagConstraints.NORTHWEST;
+        gbc.insets.top = 0;
+        auxPanel.add(getLDAPSecureAccessButton(), gbc);
+      }
       gbc.gridwidth = GridBagConstraints.REMAINDER;
       gbc.weightx = 1.0;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
       auxPanel.add(Box.createHorizontalGlue(), gbc);
     }
     addVerticalGlue(panel);
@@ -304,7 +375,8 @@
       if (defaultUserData.getServerPort() > 0)
       {
         value = String.valueOf(defaultUserData.getServerPort());
-      } else
+      }
+      else
       {
         value = "";
       }
@@ -322,6 +394,11 @@
       value = defaultUserData.getDirectoryManagerPwd();
       break;
 
+    case SECURITY_OPTIONS:
+      value = getSecurityOptionsString(defaultUserData.getSecurityOptions(),
+          true);
+      break;
+
     default:
       throw new IllegalArgumentException("Unknown field name: " +
           fieldName);
@@ -343,6 +420,11 @@
         LabelFieldDescriptor.FieldType.TEXTFIELD,
         LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PORT_FIELD_SIZE));
 
+    hm.put(FieldName.SECURITY_OPTIONS, new LabelFieldDescriptor(
+        getMsg("server-security-label"), getMsg("server-security-tooltip"),
+        LabelFieldDescriptor.FieldType.READ_ONLY,
+        LabelFieldDescriptor.LabelType.PRIMARY, 0));
+
     hm.put(FieldName.DIRECTORY_MANAGER_DN, new LabelFieldDescriptor(
         getMsg("server-directory-manager-dn-label"),
         getMsg("server-directory-manager-dn-tooltip"),
@@ -367,11 +449,20 @@
     {
       LabelFieldDescriptor desc = hm.get(fieldName);
       String defaultValue = getDefaultValue(fieldName);
-      JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
+
       JLabel label = makeJLabel(desc);
 
-      hmFields.put(fieldName, field);
-      label.setLabelFor(field);
+      if (fieldName != FieldName.SECURITY_OPTIONS)
+      {
+        JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
+        hmFields.put(fieldName, field);
+        label.setLabelFor(field);
+      }
+      else
+      {
+        lSecurity = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+            defaultValue, UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+      }
 
       hmLabels.put(fieldName, label);
     }
@@ -431,6 +522,36 @@
   }
 
   /**
+   * Returns the configure secure access button.
+   * If it does not exist creates the secure access button.
+   * @return the secure access button.
+   */
+  private JButton getLDAPSecureAccessButton()
+  {
+    if (secureAccessButton == null)
+    {
+      secureAccessButton =
+          UIFactory.makeJButton(getMsg("server-security-button-label"),
+              getMsg("server-security-button-tooltip"));
+
+      secureAccessButton.addActionListener(new ActionListener()
+      {
+        public void actionPerformed(ActionEvent ev)
+        {
+          getConfigureSecureAccessDialog().display(securityOptions);
+          if (!getConfigureSecureAccessDialog().isCancelled())
+          {
+            securityOptions =
+              getConfigureSecureAccessDialog().getSecurityOptions();
+            lSecurity.setText(getSecurityOptionsString(securityOptions, true));
+          }
+        }
+      });
+    }
+    return secureAccessButton;
+  }
+
+  /**
    * Returns the label associated with the given field name.
    * @param fieldName the field name for which we want to retrieve the JLabel.
    * @return the label associated with the given field name.
@@ -472,6 +593,7 @@
     {
       tf.addFocusListener(l);
     }
+    getLDAPSecureAccessButton().addFocusListener(l);
     getBrowseButton().addFocusListener(l);
     if (Utils.isWebStart())
     {
@@ -498,4 +620,14 @@
     }
     return s;
   }
+
+  private SecurityOptionsDialog getConfigureSecureAccessDialog()
+  {
+    if (dlg == null)
+    {
+      dlg = new SecurityOptionsDialog((JFrame)getMainWindow(), securityOptions);
+      dlg.setModal(true);
+    }
+    return dlg;
+  }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
index 8766596..37bd4ca 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -38,7 +38,6 @@
 import java.awt.event.MouseEvent;
 import java.util.HashMap;
 
-
 import javax.swing.*;
 import javax.swing.text.JTextComponent;
 import javax.swing.border.Border;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java
index 4bdaed6..fd9d540 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java
@@ -3365,7 +3365,7 @@
    * key manager provider enabled attribute.  This does not take any arguments.
    */
   public static final int MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED =
-       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 313;
+       CATEGORY_MASK_CONFIG | SEVERITY_MASK_INFORMATIONAL | 313;
 
 
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java
index bd0ad25..0e5236e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -4347,6 +4347,7 @@
 
 
 
+
   /**
    * The message ID for the message that will be used if an error occurs while
    * attempting to configure the connection security provider for a new
@@ -4378,7 +4379,13 @@
   public static final int MSGID_LDAP_CONNHANDLER_NO_TRUSTMANAGER_DN =
        CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_SEVERE_ERROR | 403;
 
-
+  /**
+   * The message ID for the message that will be used as the description of the
+   * configuration attribute specifying whether to enable the LDAPS
+   * connection handler.
+   */
+  public static final int MSGID_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE =
+       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_INFORMATIONAL | 404;
 
   /**
    * Associates a set of generic messages with the message IDs defined in this
@@ -5306,6 +5313,9 @@
                     "configuration attribute will not take effect until the " +
                     "connection handler is disabled and re-enabled, or until " +
                     "the Directory Server is restarted.");
+    registerMessage(MSGID_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE,
+                    "Specifies whether to enable the LDAPS connection " +
+                    "handler.");
     registerMessage(MSGID_LDAP_CONNHANDLER_DESCRIPTION_BACKLOG,
                     "Specifies the accept queue size, which controls the " +
                     "number of new connection attempts that may be allowed " +
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
index eab33d5..1cab65f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -6796,6 +6796,139 @@
 
 
   /**
+   * The message ID for the message that will be used as the description of the
+   * ldapsPort argument.  This does not take any arguments.
+   */
+  public static final int MSGID_CONFIGDS_DESCRIPTION_LDAPS_PORT =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 858;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to update the LDAP secure port.  This takes a single argument,
+   * which is a message explaining the problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 859;
+
+  /**
+   * The message ID for the message that will be used as the description of the
+   * enableStartTLS argument.  This does not take any arguments.
+   */
+  public static final int MSGID_CONFIGDS_DESCRIPTION_ENABLE_START_TLS =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 860;
+
+  /**
+   * The message ID for the message that will be used as the description of the
+   * Key Manager Provider DN argument for the connection handlers.  This does
+   * not take any arguments.
+   */
+  public static final int MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 861;
+
+  /**
+   * The message ID for the message that will be used as the description of the
+   * Trust Manager Provider DN argument for the connection handlers.  This does
+   * not take any arguments.
+   */
+  public static final int MSGID_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 862;
+
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to parse the DN provided for the key manager provider.  This
+   * takes two arguments, the dn valud provided by the user and a message
+   * explaining the problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 863;
+
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to parse the DN provided for the trust manager provider.  This
+   * takes two arguments, the dn valud provided by the user and a message
+   * explaining the problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 864;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to enable StartTLS.  This takes a single argument,
+   * which is a message explaining the problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_ENABLE_STARTTLS =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 865;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to enable the key manager provider.  This takes a single
+   * argument, which is a message explaining the problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_ENABLE_KEYMANAGER =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 866;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to enable the trust manager provider.  This takes a single
+   * argument, which is a message explaining the problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 867;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to update the key manager provider DN in one of the connection
+   * handlers.  This takes a single argument, which is a message explaining the
+   * problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 868;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to update the trust manager provider DN in one of the connection
+   * handlers.  This takes a single argument, which is a message explaining the
+   * problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 869;
+
+  /**
+   * The message ID for the message that will be used as the description of the
+   * Certificate Key Manager Path for the Key Manager Provider entry.  This does
+   * not take any arguments.
+   */
+  public static final int MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 870;
+
+  /**
+   * The message ID for the message that will be used as the description of the
+   * Certificate Nick Name for the connection handlers.  This does
+   * not take any arguments.
+   */
+  public static final int MSGID_CONFIGDS_DESCRIPTION_CERTNICKNAME =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 871;
+
+  /**
+   * The message ID for the message that will be used if the user provided a key
+   * manager provider path without providing a key manager provider DN.  This
+   * takes as argument the two argument names.
+   */
+  public static final int MSGID_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED =
+    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 872;
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to update the certificate nickname in one of the connection
+   * handlers.  This takes a single argument, which is a message explaining the
+   * problem that occurred.
+   */
+  public static final int MSGID_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME =
+    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 873;
+
+  /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
    */
@@ -7970,9 +8103,58 @@
     registerMessage(MSGID_CONFIGDS_DESCRIPTION_LDAP_PORT,
                     "Specifies the port on which the Directory Server should " +
                     "listen for LDAP communication.");
+    registerMessage(MSGID_CONFIGDS_DESCRIPTION_LDAPS_PORT,
+                    "Specifies the port on which the Directory Server should " +
+                    "listen for LDAPS communication.");
     registerMessage(MSGID_CONFIGDS_DESCRIPTION_JMX_PORT,
                     "Specifies the port on which the Directory Server should " +
                     "listen for JMX communication.");
+    registerMessage(MSGID_CONFIGDS_DESCRIPTION_ENABLE_START_TLS,
+                    "Specifies whether to enable or not StartTLS.");
+    registerMessage(MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN,
+                    "Specifies the DN of the key manager provider to use " +
+                    "for SSL and/or StartTLS.");
+    registerMessage(MSGID_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN,
+                    "Specifies the DN of the trust manager provider to use " +
+                    "for SSL and/or StartTLS.");
+    registerMessage(MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH,
+                    "Specifies the path of the keystore to be used by the " +
+                    "key manager provider.");
+    registerMessage(MSGID_CONFIGDS_DESCRIPTION_CERTNICKNAME,
+                    "Specifies the nickname of the certificate that the " +
+                    "connection handler should use when accepting SSL-based " +
+                    "connections or performing StartTLS negotiation.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN,
+                    "An error occurred while attempting to parse key manager " +
+                    "provider DN value \"%s\" as a DN:  %s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN,
+                    "An error occurred while attempting to parse trust " +
+                    "manager provider DN value \"%s\" as a DN:  %s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_ENABLE_STARTTLS,
+                    "An error occurred while attempting to enable StartTLS: " +
+                    "%s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_ENABLE_KEYMANAGER,
+                    "An error occurred while attempting to enable key " +
+                    "manager provider entry: %s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER,
+                    "An error occurred while attempting to enable trust " +
+                    "manager provider entry: %s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE,
+                    "An error occurred while attempting to update the key " +
+                    "manager provider DN used for LDAPS communication: " +
+                    "%s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE,
+                    "An error occurred while attempting to update the trust " +
+                    "manager provider DN used for LDAPS communication: " +
+                    "%s.");
+    registerMessage(MSGID_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED,
+                    "ERROR:  You must provide the %s argument when providing " +
+                    "the %s argument.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME,
+                    "An error occurred while attempting to update the " +
+                    "nickname of the certificate that the " +
+                    "connection handler should use when accepting SSL-based " +
+                    "connections or performing StartTLS negotiation: %s.");
     registerMessage(MSGID_CONFIGDS_DESCRIPTION_BASE_DN,
                     "Specifies the base DN for user information in the " +
                     "Directory Server.  Multiple base DNs may be provided " +
@@ -8018,6 +8200,9 @@
     registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_LDAP_PORT,
                     "An error occurred while attempting to update the port " +
                     "on which to listen for LDAP communication:  %s.");
+    registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT,
+                    "An error occurred while attempting to update the port " +
+                    "on which to listen for LDAPS communication:  %s.");
     registerMessage(MSGID_CONFIGDS_CANNOT_UPDATE_JMX_PORT,
                     "An error occurred while attempting to update the port " +
                     "on which to listen for JMX communication:  %s.");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureDS.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureDS.java
index 101aeff..517d0ac 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureDS.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureDS.java
@@ -31,6 +31,7 @@
 import java.util.LinkedList;
 
 import org.opends.server.api.ConfigHandler;
+import org.opends.server.config.BooleanConfigAttribute;
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.DNConfigAttribute;
 import org.opends.server.config.IntegerConfigAttribute;
@@ -52,6 +53,7 @@
 
 import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.messages.ConfigMessages.*;
+import static org.opends.server.messages.ExtensionsMessages.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.ProtocolMessages.*;
 import static org.opends.server.messages.ToolMessages.*;
@@ -102,6 +104,12 @@
 
 
   /**
+   * The DN of the configuration entry defining the LDAPS connection handler.
+   */
+  private static final String DN_LDAPS_CONNECTION_HANDLER =
+       "cn=LDAPS Connection Handler," + DN_CONNHANDLER_BASE;
+
+  /**
    * The DN of the configuration entry defining the JMX connection handler.
    */
   private static final String DN_JMX_CONNECTION_HANDLER =
@@ -146,15 +154,20 @@
   public static int configMain(String[] args)
   {
     BooleanArgument   showUsage;
+    BooleanArgument   enableStartTLS;
     FileBasedArgument rootPasswordFile;
     IntegerArgument   ldapPort;
+    IntegerArgument   ldapsPort;
     IntegerArgument   jmxPort;
     StringArgument    baseDNString;
     StringArgument    configClass;
     StringArgument    configFile;
     StringArgument    rootDNString;
     StringArgument    rootPassword;
-
+    StringArgument    keyManagerProviderDN;
+    StringArgument    trustManagerProviderDN;
+    StringArgument    certNickName;
+    StringArgument    keyManagerPath;
 
     String toolDescription = getMessage(MSGID_CONFIGDS_TOOL_DESCRIPTION);
     ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription,
@@ -182,12 +195,62 @@
                                      MSGID_CONFIGDS_DESCRIPTION_LDAP_PORT);
       argParser.addArgument(ldapPort);
 
+      ldapsPort = new IntegerArgument("ldapsPort", 'P', "ldapsPort", false,
+          false, true, "{ldapPort}", 636, null, true, 1, true, 65535,
+          MSGID_CONFIGDS_DESCRIPTION_LDAPS_PORT);
+      argParser.addArgument(ldapsPort);
+
+      enableStartTLS = new BooleanArgument("enableStartTLS",
+          OPTION_SHORT_START_TLS, "enableStartTLS",
+          MSGID_CONFIGDS_DESCRIPTION_ENABLE_START_TLS);
+      argParser.addArgument(enableStartTLS);
+
       jmxPort = new IntegerArgument("jmxport", 'x', "jmxPort", false, false,
           true, "{jmxPort}", SetupUtils.getDefaultJMXPort(), null, true, 1,
           true, 65535,
           MSGID_CONFIGDS_DESCRIPTION_JMX_PORT);
       argParser.addArgument(jmxPort);
 
+      keyManagerProviderDN = new StringArgument("keymanagerproviderdn",
+          'k',
+          "keyManagerProviderDN",
+          false, false,
+          true, "{keyManagerProviderDN}",
+          null,
+          null,
+          MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN);
+      argParser.addArgument(keyManagerProviderDN);
+
+      trustManagerProviderDN = new StringArgument("trustmanagerproviderdn",
+          't',
+          "trustManagerProviderDN",
+          false, false,
+          true, "{trustManagerProviderDN}",
+          null,
+          null,
+          MSGID_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN);
+      argParser.addArgument(trustManagerProviderDN);
+
+      keyManagerPath = new StringArgument("keymanagerpath",
+          'm',
+          "keyManagerPath",
+          false, false, true,
+          "{keyManagerPath}",
+          null,
+          null,
+          MSGID_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH);
+      argParser.addArgument(keyManagerPath);
+
+      certNickName = new StringArgument("certnickname",
+          'a',
+          "certNickName",
+          false, false,
+          true, "{certNickName}",
+          null,
+          null,
+          MSGID_CONFIGDS_DESCRIPTION_CERTNICKNAME);
+      argParser.addArgument(certNickName);
+
       baseDNString = new StringArgument("basedn", OPTION_SHORT_BASEDN,
                                         OPTION_LONG_BASEDN, false, true,
                                         true, OPTION_VALUE_BASEDN,
@@ -399,6 +462,86 @@
       ConfigHandler configHandler = directoryServer.getConfigHandler();
 
 
+      // Check that the key manager provided is valid.
+      if (keyManagerProviderDN.isPresent())
+      {
+        DN dn = null;
+        try
+        {
+          dn = DN.decode(keyManagerProviderDN.getValue());
+        }
+        catch (DirectoryException de)
+        {
+          int    msgID   = MSGID_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN;
+          String message = getMessage(msgID,
+              keyManagerProviderDN.getValue(),
+              de.getErrorMessage());
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+
+        try
+        {
+          configHandler.getConfigEntry(dn);
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIG_KEYMANAGER_CANNOT_GET_BASE;
+          String message = getMessage(msgID,
+              keyManagerProviderDN.getValue(),
+              String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
+
+      // Check that the trust manager provided is valid.
+      if (trustManagerProviderDN.isPresent())
+      {
+        DN dn = null;
+        try
+        {
+          dn = DN.decode(trustManagerProviderDN.getValue());
+        }
+        catch (DirectoryException de)
+        {
+          int  msgID   = MSGID_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN;
+          String message = getMessage(msgID,
+              trustManagerProviderDN.getValue(),
+              de.getErrorMessage());
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+
+        try
+        {
+          configHandler.getConfigEntry(dn);
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIG_TRUSTMANAGER_CANNOT_GET_BASE;
+          String message = getMessage(msgID,
+              trustManagerProviderDN.getValue(),
+              String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
+
+      // Check that the keystore path values are valid.
+      if (keyManagerPath.isPresent())
+      {
+        if (!keyManagerProviderDN.isPresent())
+        {
+          int    msgID   = MSGID_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED;
+          String message = getMessage(msgID,
+              keyManagerProviderDN.getLongIdentifier(),
+              keyManagerPath.getLongIdentifier());
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
+
       // If one or more base DNs were specified, then update the config
       // accordingly.
       if (baseDNs != null)
@@ -449,6 +592,36 @@
         }
       }
 
+//    If an LDAPS port was specified, then update the config accordingly.
+      if (ldapsPort.isPresent())
+      {
+        try
+        {
+          DN ldapListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
+          ConfigEntry configEntry =
+               configHandler.getConfigEntry(ldapListenerDN);
+
+          int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT;
+          IntegerConfigAttribute portAttr =
+               new IntegerConfigAttribute(ATTR_LISTEN_PORT, getMessage(msgID),
+                                          true, false, true, true, 1, true,
+                                          65535, ldapsPort.getIntValue());
+          configEntry.putConfigAttribute(portAttr);
+          msgID = MSGID_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE;
+          BooleanConfigAttribute enablePortAttr =
+            new BooleanConfigAttribute(ATTR_CONNECTION_HANDLER_ENABLED,
+                getMessage(msgID), true, true, true);
+          configEntry.putConfigAttribute(enablePortAttr);
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT;
+          String message = getMessage(msgID, String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
+
 //    If an JMX port was specified, then update the config accordingly.
       if (jmxPort.isPresent())
       {
@@ -474,6 +647,235 @@
         }
       }
 
+      // Start TLS configuration
+      if (enableStartTLS.isPresent())
+      {
+        try
+        {
+          DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
+          ConfigEntry configEntry =
+               configHandler.getConfigEntry(ldapListenerDN);
+
+          int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS;
+          BooleanConfigAttribute startTLS =
+            new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS,
+                getMessage(msgID), true, true, true);
+          configEntry.putConfigAttribute(startTLS);
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIGDS_CANNOT_ENABLE_STARTTLS;
+          String message = getMessage(msgID, String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
+
+      // Key manager provider
+      if (keyManagerProviderDN.isPresent())
+      {
+        if (enableStartTLS.isPresent() || ldapsPort.isPresent())
+        {
+          try
+          {
+            // Enable the key manager
+            DN dn = DN.decode(keyManagerProviderDN.getValue());
+            ConfigEntry configEntry = configHandler.getConfigEntry(dn);
+
+            int msgID = MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED;
+            BooleanConfigAttribute enableAttr =
+              new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
+                  getMessage(msgID), true, true, true);
+            configEntry.putConfigAttribute(enableAttr);
+          }
+          catch (Exception e)
+          {
+            int    msgID   = MSGID_CONFIGDS_CANNOT_ENABLE_KEYMANAGER;
+            String message = getMessage(msgID, String.valueOf(e));
+            System.err.println(wrapText(message, MAX_LINE_WIDTH));
+            return 1;
+          }
+        }
+
+        try
+        {
+          if (enableStartTLS.isPresent())
+          {
+            // Use the key manager specified for the LDAP connection handler.
+            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(ldapListenerDN);
+
+            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN;
+            StringConfigAttribute keyManagerProviderAttr =
+              new StringConfigAttribute(ATTR_KEYMANAGER_DN, getMessage(msgID),
+                  false, false, true, keyManagerProviderDN.getValue());
+            configEntry.putConfigAttribute(keyManagerProviderAttr);
+          }
+
+          if (ldapsPort.isPresent())
+          {
+            // Use the key manager specified for the LDAPS connection handler.
+            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(ldapsListenerDN);
+
+            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN;
+            StringConfigAttribute keyManagerProviderAttr =
+              new StringConfigAttribute(ATTR_KEYMANAGER_DN,
+                  getMessage(msgID), false, false,
+                  true, keyManagerProviderDN.getValue());
+            configEntry.putConfigAttribute(keyManagerProviderAttr);
+          }
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE;
+          String message = getMessage(msgID, String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+
+        if (keyManagerPath.isPresent())
+        {
+          try
+          {
+            // Enable the key manager
+            DN dn = DN.decode(keyManagerProviderDN.getValue());
+            ConfigEntry configEntry = configHandler.getConfigEntry(dn);
+
+            int msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_FILE;
+            StringConfigAttribute pathAttr =
+              new StringConfigAttribute(ATTR_KEYSTORE_FILE,
+                  getMessage(msgID), true, true, true,
+                  keyManagerPath.getValue());
+            configEntry.putConfigAttribute(pathAttr);
+          }
+          catch (Exception e)
+          {
+            String message = String.valueOf(e);
+            System.err.println(wrapText(message, MAX_LINE_WIDTH));
+            return 1;
+          }
+        }
+      }
+      if (trustManagerProviderDN.isPresent())
+      {
+        if (enableStartTLS.isPresent() || ldapsPort.isPresent())
+        {
+          // Enable the trust manager
+          try
+          {
+            DN dn = DN.decode(trustManagerProviderDN.getValue());
+            ConfigEntry configEntry = configHandler.getConfigEntry(dn);
+
+            int msgID = MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED;
+            BooleanConfigAttribute enableAttr =
+              new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
+                  getMessage(msgID), true, true, true);
+            configEntry.putConfigAttribute(enableAttr);
+          }
+          catch (Exception e)
+          {
+            int    msgID   = MSGID_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER;
+            String message = getMessage(msgID, String.valueOf(e));
+            System.err.println(wrapText(message, MAX_LINE_WIDTH));
+            return 1;
+          }
+        }
+
+        try
+        {
+          if (enableStartTLS.isPresent())
+          {
+            // Use the trust manager specified for the LDAP connection handler.
+            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(ldapListenerDN);
+
+            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN;
+            StringConfigAttribute trustManagerProviderAttr =
+              new StringConfigAttribute(ATTR_TRUSTMANAGER_DN,
+                  getMessage(msgID), false, false,
+                  true, trustManagerProviderDN.getValue());
+            configEntry.putConfigAttribute(trustManagerProviderAttr);
+          }
+
+          if (ldapsPort.isPresent())
+          {
+            // Use the trust manager specified for the LDAPS connection handler.
+            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(ldapsListenerDN);
+
+            int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN;
+            StringConfigAttribute trustManagerProviderAttr =
+              new StringConfigAttribute(ATTR_TRUSTMANAGER_DN,
+                  getMessage(msgID), false, false,
+                  true, trustManagerProviderDN.getValue());
+            configEntry.putConfigAttribute(trustManagerProviderAttr);
+          }
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE;
+          String message = getMessage(msgID, String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
+
+      if (certNickName.isPresent())
+      {
+        try
+        {
+          int msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME;
+          StringConfigAttribute certNickNameAttr =
+            new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME, getMessage(msgID),
+                false, false, true, certNickName.getValue());
+
+          if (ldapPort.isPresent())
+          {
+            // Use the key manager specified for the LDAP connection handler.
+            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(ldapListenerDN);
+
+            configEntry.putConfigAttribute(certNickNameAttr);
+          }
+
+          if (ldapsPort.isPresent())
+          {
+            // Use the key manager specified for the LDAPS connection handler.
+            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(ldapsListenerDN);
+
+            configEntry.putConfigAttribute(certNickNameAttr);
+          }
+
+          if (jmxPort.isPresent())
+          {
+            msgID = MSGID_JMX_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME;
+            certNickNameAttr = new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME,
+                getMessage(msgID), false, false, true, certNickName.getValue());
+
+            // Use the key manager specified for the JMX connection handler.
+            DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
+            ConfigEntry configEntry =
+              configHandler.getConfigEntry(jmxListenerDN);
+
+            configEntry.putConfigAttribute(certNickNameAttr);
+          }
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME;
+          String message = getMessage(msgID, String.valueOf(e));
+          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          return 1;
+        }
+      }
 
       // If a root user DN and password were specified, then update the config
       // accordingly.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/CertificateManager.java b/opendj-sdk/opends/src/server/org/opends/server/util/CertificateManager.java
index 82961ca..7851ddb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/CertificateManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/CertificateManager.java
@@ -332,6 +332,7 @@
       aliasList.add(aliasEnumeration.nextElement());
     }
 
+
     String[] aliases = new String[aliasList.size()];
     return aliasList.toArray(aliases);
   }
@@ -646,7 +647,6 @@
   }
 
 
-
   /**
    * Removes the specified certificate from the key store.
    *
@@ -855,6 +855,19 @@
     {
       throw new KeyStoreException(String.valueOf(e), e);
     }
+    finally
+    {
+      if (keyStoreInputStream != null)
+      {
+        try
+        {
+          keyStoreInputStream.close();
+        }
+        catch (Throwable t)
+        {
+        }
+      }
+    }
   }
 }
 

--
Gitblit v1.10.0