>From 4b8dd5d87a629b269dc6fc134a747ca5fe53bfc1 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Fri, 13 Apr 2012 13:51:32 -0400
Subject: [PATCH] RESTful servlet to configure system in a single servlet.

Installation code common to the panels and the installation servlet are extracted to a
ConfigurationUtils file.  The panel code will be cleaned up to use the code in this
class in a later commit.

Contains restful client and test driver code.  The test driver code should be modified
and placed in a junit/system test framework.  Installation has been tested to work with
the following installations: master CA, clone CA, KRA, OCSP, TKS, subordinate CA, CA
signed by external CA (parts 1 and 2).

Ticket #155
---
 .classpath                                         |    2 +
 base/ca/shared/webapps/ca/WEB-INF/web.xml          |   27 +
 .../cms/servlet/test/ConfigurationTest.java        | 1048 ++++++
 base/common/src/CMakeLists.txt                     |   22 +-
 .../src/com/netscape/cms/servlet/csadmin/Cert.java |    9 +
 .../com/netscape/cms/servlet/csadmin/CertUtil.java |    9 +-
 .../csadmin/ConfigurationErrorInterceptor.java     |   64 +
 .../servlet/csadmin/ConfigurationRESTClient.java   |  197 ++
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 3452 ++++++++++++++++++++
 .../csadmin/SystemConfigurationResource.java       |   66 +
 .../SystemConfigurationResourceService.java        |  944 ++++++
 .../cms/servlet/csadmin/model/CertData.java        |  270 ++
 .../servlet/csadmin/model/ConfigurationData.java   |  724 ++++
 .../csadmin/model/ConfigurationResponseData.java   |  120 +
 .../cms/servlet/csadmin/model/DomainInfo.java      |  155 +
 .../cms/servlet/csadmin/model/InstallToken.java    |   50 +
 .../servlet/csadmin/model/InstallTokenRequest.java |  101 +
 .../servlet/csadmin/model/SecurityDomainHost.java  |   40 +
 .../csadmin/model/SecurityDomainHostList.java      |   53 +
 base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml      |   27 +
 base/setup/pkicommon.pm                            |    5 +-
 base/setup/pkicreate                               |   14 +-
 base/tks/shared/webapps/tks/WEB-INF/web.xml        |   27 +
 23 files changed, 7419 insertions(+), 7 deletions(-)
 create mode 100644 base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java

diff --git a/.classpath b/.classpath
index 3f38dd98b46595ee1699a8fec1c34489c838b515..cb9c52f1ec00d59dfd4577d749525254a4ce0a8a 100644
--- a/.classpath
+++ b/.classpath
@@ -14,6 +14,7 @@
 	<classpathentry excluding="**/CMakeLists.txt" kind="src" path="base/util/src"/>
 	<classpathentry excluding="**/CMakeLists.txt" kind="src" path="base/silent/src"/>
 	<classpathentry kind="src" path="base/kra/functional/src"/>
+	<classpathentry kind="src" path="base/common/functional/src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="lib" path="/usr/share/java/apache-commons-cli.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/apache-commons-logging.jar"/>
@@ -39,5 +40,6 @@
 	<classpathentry kind="lib" path="/usr/share/java/xerces-j2.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/xml-commons-apis.jar"/>
 	<classpathentry kind="lib" path="/usr/share/tomcat6/lib/catalina.jar"/>
+	<classpathentry kind="lib" path="/usr/share/java/istack-commons-runtime.jar"/>
 	<classpathentry kind="output" path="build/classes"/>
 </classpath>
diff --git a/base/ca/shared/webapps/ca/WEB-INF/web.xml b/base/ca/shared/webapps/ca/WEB-INF/web.xml
index 5e91977aa39c3febb1997d985acc32e00114fb58..692cb4898cfe2133307a6a7ce75dff418ec82834 100644
--- a/base/ca/shared/webapps/ca/WEB-INF/web.xml
+++ b/base/ca/shared/webapps/ca/WEB-INF/web.xml
@@ -1900,6 +1900,28 @@
                          <param-value> /agent/ca/doRevoke       </param-value> </init-param>
    </servlet>
 
+   <context-param>
+      <param-name>resteasy.scan</param-name>
+      <param-value>true</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.servlet.mapping.prefix</param-name>
+      <param-value>/pki</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.resource.method-interceptors</param-name>
+      <param-value>
+         org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
+      </param-value>
+   </context-param>
+
+   <servlet>
+      <servlet-name>Resteasy</servlet-name>
+      <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+   </servlet>
+   
 [PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
    <filter-mapping>
       <filter-name>   AgentRequestFilter          </filter-name>
@@ -1943,6 +1965,11 @@
 [PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
 
    <servlet-mapping>
+      <servlet-name>Resteasy</servlet-name>
+      <url-pattern>/pki/*</url-pattern>
+   </servlet-mapping>
+   
+   <servlet-mapping>
       <servlet-name>  caacl  </servlet-name>
       <url-pattern>   /acl  </url-pattern>
    </servlet-mapping>
diff --git a/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java b/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ac322d63ce1393b3a4ea23bf6829d77bcaa82b0
--- /dev/null
+++ b/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java
@@ -0,0 +1,1048 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.test;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import netscape.security.x509.X500Name;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.POPOPrivKey;
+import org.mozilla.jss.pkix.crmf.ProofOfPossession;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cms.servlet.csadmin.ConfigurationRESTClient;
+import com.netscape.cms.servlet.csadmin.model.CertData;
+import com.netscape.cms.servlet.csadmin.model.ConfigurationData;
+import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * @author alee
+ *
+ */
+public class ConfigurationTest {
+
+    public static void usage(Options options) {
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.printHelp("ConfigurationTest", options);
+        System.exit(1);
+    }
+
+    public static void main(String args[]) throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException {
+        String host = null;
+        String port = null;
+        String cstype = null;
+        String token_pwd = null;
+        String db_dir = "./";
+        String protocol = "https";
+        String pin = null;
+        String extCertFile = null;
+        String extChainFile = null;
+        int testnum=1;
+
+        // parse command line arguments
+        Options options = new Options();
+        options.addOption("t", true, "Subsystem type");
+        options.addOption("h", true, "Hostname of the CS subsystem");
+        options.addOption("p", true, "Port of the CS subsystem");
+        options.addOption("w", true, "Token password");
+        options.addOption("d", true, "Directory for tokendb");
+        options.addOption("s", true, "preop pin");
+        options.addOption("e", true, "File for externally signed signing cert");
+        options.addOption("g", true, "File for external CA cert chain");
+        options.addOption("x", true, "Test number");
+
+        try {
+            CommandLineParser parser = new PosixParser();
+            CommandLine cmd = parser.parse(options, args);
+
+            if (cmd.hasOption("t")) {
+                cstype = cmd.getOptionValue("t");
+            } else {
+                System.err.println("Error: no subsystem type provided.");
+                usage(options);
+            }
+
+            if (cmd.hasOption("h")) {
+                host = cmd.getOptionValue("h");
+            } else {
+                System.err.println("Error: no hostname provided.");
+                usage(options);
+            }
+
+            if (cmd.hasOption("p")) {
+                port = cmd.getOptionValue("p");
+            } else {
+                System.err.println("Error: no port provided");
+                usage(options);
+            }
+
+            if (cmd.hasOption("w")) {
+                token_pwd = cmd.getOptionValue("w");
+            } else {
+                System.err.println("Error: no token password provided");
+                usage(options);
+            }
+
+            if (cmd.hasOption("d")) {
+                db_dir = cmd.getOptionValue("d");
+            }
+
+            if (cmd.hasOption("s")) {
+                pin = cmd.getOptionValue("s");
+            }
+
+            if (cmd.hasOption("e")) {
+                extCertFile = cmd.getOptionValue("e");
+            }
+
+            if (cmd.hasOption("g")) {
+                extChainFile = cmd.getOptionValue("g");
+            }
+
+            if (cmd.hasOption("x")) {
+                testnum = Integer.parseInt(cmd.getOptionValue("x"));
+            }
+        } catch (ParseException e) {
+            System.err.println("Error in parsing command line options: " + e.getMessage());
+            usage(options);
+        }
+
+     // Initialize token
+        try {
+            CryptoManager.initialize(db_dir);
+        } catch (AlreadyInitializedException e) {
+            // it is ok if it is already initialized
+        } catch (Exception e) {
+            System.out.println("INITIALIZATION ERROR: " + e.toString());
+            System.exit(1);
+        }
+
+        // log into token
+        CryptoManager manager = null;
+        CryptoToken token = null;
+        try {
+            manager = CryptoManager.getInstance();
+            token = manager.getInternalKeyStorageToken();
+            Password password = new Password(token_pwd.toCharArray());
+            try {
+                token.login(password);
+            } catch (Exception e) {
+                System.out.println("login Exception: " + e.toString());
+                if (!token.isLoggedIn()) {
+                    token.initPassword(password, password);
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("Exception in logging into token:" + e.toString());
+        }
+
+        String baseUri = protocol + "://" + host + ":" + port + "/" + cstype + "/pki";
+        ConfigurationRESTClient client = null;
+        try {
+            client = new ConfigurationRESTClient(baseUri, null);
+        } catch (URISyntaxException e1) {
+            e1.printStackTrace();
+            System.exit(1);
+        }
+
+        ConfigurationData data = null;
+        switch (testnum) {
+        case 1:
+            data = constructCAData(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 2:
+            data = constructCloneCAData(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 3:
+            data = constructKRAData(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 4:
+            data = constructOCSPData(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 5:
+            data = constructTKSData(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 6:
+            data = constructSubCAData(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 7:
+            data = constructExternalCADataPart1(host, port, pin, db_dir, token_pwd, token);
+            break;
+        case 8:
+            data = constructExternalCADataPart2(host, port, pin, db_dir, token_pwd, token, extCertFile, extChainFile);
+            break;
+        default:
+            System.out.println("Invalid test");
+            System.exit(1);
+        }
+
+        ConfigurationResponseData response = client.configure(data);
+
+        System.out.println("status: " + response.getStatus());
+        System.out.println("adminCert: " + response.getAdminCert().getCert());
+        Collection<CertData> certs = response.getSystemCerts();
+        Iterator<CertData> iterator = certs.iterator();
+        while (iterator.hasNext()) {
+            CertData cdata = iterator.next();
+            System.out.println("tag: " + cdata.getTag());
+            System.out.println("cert: " + cdata.getCert());
+            System.out.println("request: " + cdata.getRequest());
+        }
+
+    }
+
+    private static ConfigurationData constructCAData(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+        data.setSecurityDomainType(ConfigurationData.NEW_DOMAIN);
+        data.setSecurityDomainName("Testca2 security domain");
+        data.setIsClone("false");
+        data.setHierarchy("root");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test ca subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testca2");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testca2");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testca.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=CA Administrator of Instance testca, UID=admin, E=alee@redhat.com, o=testca2";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert1 = new CertData();
+        cert1.setTag("signing");
+        cert1.setKeyAlgorithm("SHA256withRSA");
+        cert1.setKeySize("2048");
+        cert1.setKeyType("rsa");
+        cert1.setNickname("signingCert testca");
+        cert1.setSigningAlgorithm("SHA256withRSA");
+        cert1.setSubjectDN("CN=CA Signing Certificate");
+        cert1.setToken("Internal Key Storage Token");
+
+        systemCerts.add(cert1);
+
+        CertData cert2 = new CertData();
+        cert2.setTag("ocsp_signing");
+        cert2.setKeyAlgorithm("SHA256withRSA");
+        cert2.setKeySize("2048");
+        cert2.setKeyType("rsa");
+        cert2.setNickname("ocspSigningCert testca");
+        cert2.setSigningAlgorithm("SHA256withRSA");
+        cert2.setSubjectDN("CN= CA OCSP Signing Certificate");
+        cert2.setToken("Internal Key Storage Token");
+        systemCerts.add(cert2);
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testca");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testca");
+        cert4.setSubjectDN("CN=CA Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testca");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=CA Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructSubCAData(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+
+        data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN);
+        data.setSecurityDomainUri("https://" + host + ":9225");
+        data.setSecurityDomainUser("admin");
+        data.setSecurityDomainPassword("redhat123");
+
+        data.setIsClone("false");
+        data.setHierarchy("join");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test subca subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testsubca");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testsubca");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testsubca.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=CA Administrator of Instance testsubca, UID=admin, E=alee@redhat.com, o=testsubca";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        data.setIssuingCA("https://" + host + ":9224");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert1 = new CertData();
+        cert1.setTag("signing");
+        cert1.setKeyAlgorithm("SHA256withRSA");
+        cert1.setKeySize("2048");
+        cert1.setKeyType("rsa");
+        cert1.setNickname("signingCert testsubca");
+        cert1.setSigningAlgorithm("SHA256withRSA");
+        cert1.setSubjectDN("CN=SubCA Signing Certificate");
+        cert1.setToken("Internal Key Storage Token");
+
+        systemCerts.add(cert1);
+
+        CertData cert2 = new CertData();
+        cert2.setTag("ocsp_signing");
+        cert2.setKeyAlgorithm("SHA256withRSA");
+        cert2.setKeySize("2048");
+        cert2.setKeyType("rsa");
+        cert2.setNickname("ocspSigningCert testsubca");
+        cert2.setSigningAlgorithm("SHA256withRSA");
+        cert2.setSubjectDN("CN= SubCA OCSP Signing Certificate");
+        cert2.setToken("Internal Key Storage Token");
+        systemCerts.add(cert2);
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testsubca");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testsubca");
+        cert4.setSubjectDN("CN=SubCA Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testsubca");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=SubCA Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructExternalCADataPart1(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+
+        data.setSecurityDomainType(ConfigurationData.NEW_DOMAIN);
+        data.setSecurityDomainName("External CA security domain");
+
+        data.setIsClone("false");
+        data.setHierarchy("join");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test external ca subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testexternalca");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testexternalca");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testexternalca.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=CA Administrator of Instance testexternalca, UID=admin, E=alee@redhat.com, o=testexternalca";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        data.setIssuingCA("External CA");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert1 = new CertData();
+        cert1.setTag("signing");
+        cert1.setKeyAlgorithm("SHA256withRSA");
+        cert1.setKeySize("2048");
+        cert1.setKeyType("rsa");
+        cert1.setNickname("signingCert testexternalca");
+        cert1.setSigningAlgorithm("SHA256withRSA");
+        cert1.setSubjectDN("CN=External CA Signing Certificate");
+        cert1.setToken("Internal Key Storage Token");
+
+        systemCerts.add(cert1);
+
+        CertData cert2 = new CertData();
+        cert2.setTag("ocsp_signing");
+        cert2.setKeyAlgorithm("SHA256withRSA");
+        cert2.setKeySize("2048");
+        cert2.setKeyType("rsa");
+        cert2.setNickname("ocspSigningCert testexternalca");
+        cert2.setSigningAlgorithm("SHA256withRSA");
+        cert2.setSubjectDN("CN= External CA OCSP Signing Certificate");
+        cert2.setToken("Internal Key Storage Token");
+        systemCerts.add(cert2);
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testexternalca");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testexternalca");
+        cert4.setSubjectDN("CN=External CA Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testexternalca");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=SubCA Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructExternalCADataPart2(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token, String extCertFile, String extChainFile)
+            throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+
+        data.setSecurityDomainType(ConfigurationData.NEW_DOMAIN);
+        data.setSecurityDomainName("External CA security domain");
+
+        data.setIsClone("false");
+        data.setHierarchy("join");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test external ca subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testexternalca");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testexternalca");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testexternalca.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=CA Administrator of Instance testexternalca, UID=admin, E=alee@redhat.com, o=testexternalca";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        data.setIssuingCA("External CA");
+        data.setStepTwo("true");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert1 = new CertData();
+        cert1.setTag("signing");
+        cert1.setKeyAlgorithm("SHA256withRSA");
+        cert1.setKeySize("2048");
+        cert1.setKeyType("rsa");
+        cert1.setNickname("signingCert testexternalca");
+        cert1.setSigningAlgorithm("SHA256withRSA");
+        cert1.setSubjectDN("CN=External CA Signing Certificate");
+        cert1.setToken("Internal Key Storage Token");
+
+        String extCert = "";
+        BufferedReader in = new BufferedReader(new FileReader(extCertFile));
+        while (in.ready()) {
+            extCert += in.readLine();
+        }
+        in.close();
+        cert1.setCert(extCert);
+
+        String extCertChain = "";
+        in = new BufferedReader(new FileReader(extChainFile));
+        while (in.ready()) {
+            extCertChain += in.readLine();
+        }
+        in.close();
+        cert1.setCertChain(extCertChain);
+
+        systemCerts.add(cert1);
+
+        CertData cert2 = new CertData();
+        cert2.setTag("ocsp_signing");
+        cert2.setKeyAlgorithm("SHA256withRSA");
+        cert2.setKeySize("2048");
+        cert2.setKeyType("rsa");
+        cert2.setNickname("ocspSigningCert testexternalca");
+        cert2.setSigningAlgorithm("SHA256withRSA");
+        cert2.setSubjectDN("CN= External CA OCSP Signing Certificate");
+        cert2.setToken("Internal Key Storage Token");
+        systemCerts.add(cert2);
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testexternalca");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testexternalca");
+        cert4.setSubjectDN("CN=External CA Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testexternalca");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=SubCA Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructCloneCAData(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+        data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN);
+        data.setSecurityDomainUri("https://" + host + ":9225");
+        data.setSecurityDomainUser("admin");
+        data.setSecurityDomainPassword("redhat123");
+
+        data.setIsClone("true");
+        data.setCloneUri("https://" + host + ":9224" );
+        data.setP12File("master.p12");
+        data.setP12Password("redhat123");
+
+        data.setHierarchy("root");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test clone ca subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7494");
+        data.setBaseDN("o=testca2");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testca2");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("false");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testca");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructKRAData(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+
+        data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN);
+        data.setSecurityDomainUri("https://" + host + ":9225");
+        data.setSecurityDomainUser("admin");
+        data.setSecurityDomainPassword("redhat123");
+
+        data.setIsClone("false");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test kra subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testkra22");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testkra");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testkra.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=KRA Administrator of Instance testkra, UID=admin, E=alee@redhat.com, o=testkra22";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        data.setIssuingCA("https://" + host + ":9224");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert1 = new CertData();
+        cert1.setTag("transport");
+        cert1.setKeyAlgorithm("SHA256withRSA");
+        cert1.setKeySize("2048");
+        cert1.setKeyType("rsa");
+        cert1.setNickname("transportCert testkra");
+        cert1.setSigningAlgorithm("SHA256withRSA");
+        cert1.setSubjectDN("CN=KRA Transport Certificate");
+        cert1.setToken("Internal Key Storage Token");
+
+        systemCerts.add(cert1);
+
+        CertData cert2 = new CertData();
+        cert2.setTag("storage");
+        cert2.setKeyAlgorithm("SHA256withRSA");
+        cert2.setKeySize("2048");
+        cert2.setKeyType("rsa");
+        cert2.setNickname("storageCert testkra");
+        cert2.setSigningAlgorithm("SHA256withRSA");
+        cert2.setSubjectDN("CN= KRA Storage Certificate");
+        cert2.setToken("Internal Key Storage Token");
+        systemCerts.add(cert2);
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testkra");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testkra");
+        cert4.setSubjectDN("CN=KRA Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testkra");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=KRA Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructOCSPData(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+
+        data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN);
+        data.setSecurityDomainUri("https://" + host + ":9225");
+        data.setSecurityDomainUser("admin");
+        data.setSecurityDomainPassword("redhat123");
+
+        data.setIsClone("false");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test ocsp subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testocsp22");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testocsp22");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testocsp.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=OCSP Administrator of Instance testocsp, UID=admin, E=alee@redhat.com, o=testocsp22";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        data.setIssuingCA("https://" + host + ":9224");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+        CertData cert1 = new CertData();
+        cert1.setTag("signing");
+        cert1.setKeyAlgorithm("SHA256withRSA");
+        cert1.setKeySize("2048");
+        cert1.setKeyType("rsa");
+        cert1.setNickname("ocspSigningCert testocsp");
+        cert1.setSigningAlgorithm("SHA256withRSA");
+        cert1.setSubjectDN("CN=OCSP Signing Certificate");
+        cert1.setToken("Internal Key Storage Token");
+
+        systemCerts.add(cert1);
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testocsp");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testocsp");
+        cert4.setSubjectDN("CN=OCSP Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testocsp");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=OCSP Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static ConfigurationData constructTKSData(String host, String port, String pin, String db_dir,
+            String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException,
+            InvalidBERException {
+        ConfigurationData data = new ConfigurationData();
+        data.setPin(pin);
+
+        data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN);
+        data.setSecurityDomainUri("https://" + host + ":9225");
+        data.setSecurityDomainUser("admin");
+        data.setSecurityDomainPassword("redhat123");
+
+        data.setIsClone("false");
+        data.setToken(ConfigurationData.TOKEN_DEFAULT);
+        data.setSubsystemName("test tks subsystem");
+
+        data.setDsHost(host);
+        data.setDsPort("7389");
+        data.setBaseDN("o=testtks22");
+        data.setBindDN("cn=Directory Manager");
+        data.setDatabase("o=testtks22");
+        data.setBindpwd("redhat123");
+        data.setRemoveData("true");
+        data.setSecureConn("false");
+
+        data.setBackupKeys("true");
+        data.setBackupFile("/tmp/testtks.p12");
+        data.setBackupPassword("redhat123");
+
+        data.setAdminEmail("alee@redhat.com");
+        data.setAdminName("admin");
+        data.setAdminPassword("redhat123");
+        data.setAdminProfileID("caAdminCert");
+        data.setAdminUID("admin");
+        String subjectdn = "CN=TKS Administrator of Instance testtks, UID=admin, E=alee@redhat.com, o=testtks22";
+        data.setAdminSubjectDN(subjectdn);
+
+        String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false);
+        data.setAdminCertRequest(crmf_request);
+        data.setAdminCertRequestType("crmf");
+
+        data.setIssuingCA("https://" + host + ":9224");
+
+        // create system certs
+        Collection<CertData> systemCerts = new ArrayList<CertData>();
+
+        CertData cert3 = new CertData();
+        cert3.setTag("sslserver");
+        cert3.setKeyAlgorithm("SHA256withRSA");
+        cert3.setKeySize("2048");
+        cert3.setKeyType("rsa");
+        cert3.setNickname("sslServerCert testtks");
+        cert3.setSubjectDN("CN=" + host);
+        cert3.setToken("Internal Key Storage Token");
+        systemCerts.add(cert3);
+
+        CertData cert4 = new CertData();
+        cert4.setTag("subsystem");
+        cert4.setKeyAlgorithm("SHA256withRSA");
+        cert4.setKeySize("2048");
+        cert4.setKeyType("rsa");
+        cert4.setNickname("subsystemCert testtks");
+        cert4.setSubjectDN("CN=TKS Subsystem Certificate");
+        cert4.setToken("Internal Key Storage Token");
+        systemCerts.add(cert4);
+
+        CertData cert5 = new CertData();
+        cert5.setTag("audit_signing");
+        cert5.setKeyAlgorithm("SHA256withRSA");
+        cert5.setKeySize("2048");
+        cert5.setKeyType("rsa");
+        cert5.setNickname("auditSigningCert testtks");
+        cert5.setSigningAlgorithm("SHA256withRSA");
+        cert5.setSubjectDN("CN=TKS Audit Signing Certificate");
+        cert5.setToken("Internal Key Storage Token");
+        systemCerts.add(cert5);
+
+        data.setSystemCerts(systemCerts);
+
+        return data;
+    }
+
+    private static String generateCRMFRequest(CryptoToken token, String keysize, String subjectdn, boolean dualkey)
+            throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException {
+        KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA);
+
+        Integer x = new Integer(keysize);
+        int key_len = x.intValue();
+
+        kg.initialize(key_len);
+
+        // 1st key pair
+        KeyPair pair = kg.genKeyPair();
+
+        // create CRMF
+        CertTemplate certTemplate = new CertTemplate();
+
+        certTemplate.setVersion(new INTEGER(2));
+
+        if (subjectdn != null) {
+            X500Name name = new X500Name(subjectdn);
+            ByteArrayInputStream cs = new ByteArrayInputStream(name.getEncoded());
+            Name n = (Name) Name.getTemplate().decode(cs);
+            certTemplate.setSubject(n);
+        }
+
+        certTemplate.setPublicKey(new SubjectPublicKeyInfo(pair.getPublic()));
+
+        SEQUENCE seq = new SEQUENCE();
+        CertRequest certReq = new CertRequest(new INTEGER(1), certTemplate,
+                seq);
+        byte popdata[] = { 0x0, 0x3, 0x0 };
+
+        ProofOfPossession pop = ProofOfPossession.createKeyEncipherment(
+                POPOPrivKey.createThisMessage(new BIT_STRING(popdata, 3)));
+
+        CertReqMsg crmfMsg = new CertReqMsg(certReq, pop, null);
+
+        SEQUENCE s1 = new SEQUENCE();
+
+        // 1st : Encryption key
+
+        s1.addElement(crmfMsg);
+
+        // 2nd : Signing Key
+
+        if (dualkey) {
+            System.out.println("dualkey = true");
+            SEQUENCE seq1 = new SEQUENCE();
+            CertRequest certReqSigning = new CertRequest(new INTEGER(1),
+                    certTemplate, seq1);
+            CertReqMsg signingMsg = new CertReqMsg(certReqSigning, pop, null);
+
+            s1.addElement(signingMsg);
+        }
+
+        byte encoded[] = ASN1Util.encode(s1);
+
+        // BASE64Encoder encoder = new BASE64Encoder();
+        // String Req1 = encoder.encodeBuffer(encoded);
+        String Req1 = Utils.base64encode(encoded);
+        return Req1;
+    }
+}
diff --git a/base/common/src/CMakeLists.txt b/base/common/src/CMakeLists.txt
index 43f3a5a773dbd33c3824a78cf1e6f95359295896..3cfd3ba012691ae0365093d7061e696b54820ffd 100644
--- a/base/common/src/CMakeLists.txt
+++ b/base/common/src/CMakeLists.txt
@@ -76,6 +76,13 @@ find_file(RESTEASY_JAXRS_JAR
         /usr/share/java/resteasy
 )
 
+find_file(HTTPCLIENT_JAR
+    NAMES
+        httpclient.jar
+    PATHS
+        /usr/share/java/httpcomponents
+)
+
 set(pki-certsrv_java_SRCS
     com/netscape/certsrv/apps/ICommandQueue.java
     com/netscape/certsrv/apps/CMS.java
@@ -647,6 +654,19 @@ set(pki-cms_java_SRCS
     com/netscape/cms/servlet/csadmin/DownloadPKCS12.java
     com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java
     com/netscape/cms/servlet/csadmin/NamePanel.java
+    com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+    com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java
+    com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java
+    com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java
+    com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java
+    com/netscape/cms/servlet/csadmin/model/CertData.java
+    com/netscape/cms/servlet/csadmin/model/ConfigurationData.java
+    com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java
+    com/netscape/cms/servlet/csadmin/model/DomainInfo.java
+    com/netscape/cms/servlet/csadmin/model/InstallToken.java
+    com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java
+    com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java
+    com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java
     com/netscape/cms/servlet/wizard/WizardServlet.java
     com/netscape/cms/servlet/wizard/IWizardPanel.java
     com/netscape/cms/servlet/processors/PKCS10Processor.java
@@ -1042,7 +1062,7 @@ set(pki-cmsbundle_RCS
 set(CMAKE_JAVA_INCLUDE_PATH
     ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
     ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR} ${XALAN_JAR} ${XERCES_JAR}
-    ${JSS_JAR} ${COMMONS_CODEC_JAR} ${TOMCAT_CATALINA_JAR} ${SYMKEY_JAR} ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR})
+    ${JSS_JAR} ${COMMONS_CODEC_JAR} ${TOMCAT_CATALINA_JAR} ${SYMKEY_JAR} ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${HTTPCLIENT_JAR})
 
 set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
 
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java b/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java
index 0aedded83bfe3ae86a21f47747c5f99ff9fe8b72..066f9dea12940612a2cc367a291bd592fb489ee6 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java
@@ -33,6 +33,7 @@ public class Cert {
     private boolean mEnable = true;
     private boolean mSigningRequired = false;
     private String mSubsystem = "";
+    private String certChain = "";
 
     public Cert(String tokenName, String nickName, String certTag) {
         mTokenname = tokenName;
@@ -176,4 +177,12 @@ public class Cert {
     public void setCustomCurvename(String curve) {
         mCustomCurvename = curve;
     }
+
+    public String getCertChain() {
+        return certChain;
+    }
+
+    public void setCertChain(String certChain) {
+        this.certChain = certChain;
+    }
 }
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
index e3068d7b3230c07ebc4c941b0b37da699126c852..35ec7c515050a847577efc8a858be0578a06e0ca 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
@@ -194,7 +194,9 @@ public class CertUtil {
             return certReqs;
         } catch (Throwable e) {
             CMS.debug(e);
-            context.put("errorString", e.toString());
+            if (context != null) {
+                context.put("errorString", e.toString());
+            }
             CMS.debug("CertUtil getPKCS10: " + e.toString());
             throw new IOException(e.toString());
         }
@@ -453,8 +455,9 @@ public class CertUtil {
         }
 
         if (cr == null) {
-            context.put("errorString",
-                    "Ceritifcate Authority is not ready to serve.");
+            if (context != null) {
+                context.put("errorString", "Ceritifcate Authority is not ready to serve.");
+            }
             throw new IOException("Ceritifcate Authority is not ready to serve.");
         }
 
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..d98d8f93dccb362df518e5780d2695ef1efd8312
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java
@@ -0,0 +1,64 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.client.core.ClientErrorInterceptor;
+
+import com.netscape.cms.servlet.base.CMSException;
+
+/**
+ * @author alee
+ *
+ */
+public class ConfigurationErrorInterceptor implements ClientErrorInterceptor {
+
+    public void handle(ClientResponse<?> response) {
+
+        // handle HTTP code 4xx and 5xx
+        int code = response.getResponseStatus().getStatusCode();
+        if (code < 400) return;
+
+        MultivaluedMap<String, String> headers = response.getHeaders();
+        String contentType = headers.getFirst("Content-Type");
+
+        // handle XML content only
+        if (!contentType.startsWith(MediaType.TEXT_XML)) return;
+
+        CMSException exception;
+
+        try {
+            // Requires RESTEasy 2.3.2
+            // https://issues.jboss.org/browse/RESTEASY-652
+            CMSException.Data data = response.getEntity(CMSException.Data.class);
+
+            Class<?> clazz = Class.forName(data.className);
+            exception = (CMSException) clazz.getConstructor(CMSException.Data.class).newInstance(data);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return;
+        }
+
+        throw exception;
+    }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..330cdf19dc3242251e86fb4a02c9b300f9b0bc57
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java
@@ -0,0 +1,197 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeSocketFactory;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpParams;
+import org.jboss.resteasy.client.ClientExecutor;
+import org.jboss.resteasy.client.ProxyFactory;
+import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLSocket;
+
+import com.netscape.cms.servlet.csadmin.model.ConfigurationData;
+import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData;
+import com.netscape.cms.servlet.csadmin.model.InstallToken;
+import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest;
+
+
+/**
+ * @author alee
+ *
+ */
+public class ConfigurationRESTClient {
+    private class ServerCertApprovalCB implements SSLCertificateApprovalCallback {
+
+        public boolean approve(org.mozilla.jss.crypto.X509Certificate servercert,
+                SSLCertificateApprovalCallback.ValidityStatus status) {
+
+            //For now lets just accept the server cert. This is a test tool, being
+            // pointed at a well known instance.
+
+
+            if (servercert != null) {
+                System.out.println("Peer cert details: " +
+                        "\n     subject: " + servercert.getSubjectDN().toString() +
+                        "\n     issuer:  " + servercert.getIssuerDN().toString() +
+                        "\n     serial:  " + servercert.getSerialNumber().toString()
+                        );
+            }
+
+            SSLCertificateApprovalCallback.ValidityItem item;
+            Enumeration<?> errors = status.getReasons();
+            int i = 0;
+            while (errors.hasMoreElements()) {
+                i++;
+                item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement();
+                System.out.println("item " + i +
+                        " reason=" + item.getReason() +
+                        " depth=" + item.getDepth());
+
+                int reason = item.getReason();
+
+                if (reason ==
+                        SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER ||
+                        reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
+
+                    //Allow these two since we haven't necessarily installed the CA cert for trust
+                    // and we are choosing "localhost" as the host for this client.
+
+                    return true;
+
+                }
+            }
+
+            //For other errors return false
+            return false;
+        }
+    }
+    
+    private class JSSProtocolSocketFactory implements SchemeSocketFactory, LayeredSchemeSocketFactory {
+        @Override
+        public Socket createSocket(HttpParams params)
+                throws IOException {
+            return null;
+        }
+
+        @Override
+        public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress,
+                InetSocketAddress localAddress, HttpParams params)
+                throws IOException, UnknownHostException {
+            Socket socket;
+            String hostName = null;
+            int port = 0;
+            if (remoteAddress != null) {
+                hostName = remoteAddress.getHostName();
+                port = remoteAddress.getPort();
+
+            }
+
+            int localPort = 0;
+            InetAddress localAddr = null;
+            if (localAddress != null) {
+                localPort = localAddress.getPort();
+                localAddr = localAddress.getAddress();
+            }
+
+            if (sock == null) {
+                socket = new SSLSocket(InetAddress.getByName(hostName), port, localAddr, localPort,
+                        new ServerCertApprovalCB(), null);
+
+            } else {
+                socket = new SSLSocket(sock, hostName, new ServerCertApprovalCB(), null);
+            }
+
+            return socket;
+        }
+
+        @Override
+        public boolean isSecure(Socket sock) {
+            //We only use this factory in the case of SSL Connections
+            return true;
+        }
+
+        @Override
+        public Socket createLayeredSocket(Socket arg0, String arg1, int arg2, boolean arg3) throws IOException,
+                UnknownHostException {
+            //This method implementation is required to get SSL working.
+            return null;
+        }
+    }
+
+    private String clientCertNickname;
+    private SystemConfigurationResource configClient;
+
+    public ConfigurationRESTClient(String baseUri, String clientCertNick) throws URISyntaxException {
+
+        // For SSL we are assuming the caller has already intialized JSS and has
+        // a valid CryptoManager and CryptoToken
+        // optional clientCertNickname is provided for use if required.
+
+
+        URI uri = new URI(baseUri);
+        
+        String protocol = uri.getScheme();
+        int port = uri.getPort();
+ 
+        clientCertNickname = null;
+        HttpClient httpclient = new DefaultHttpClient();
+        if(protocol != null && protocol.equals("https")) {
+            if (clientCertNick != null) {
+                clientCertNickname = clientCertNick;
+            }
+ 
+            Scheme scheme = new Scheme("https",port, new JSSProtocolSocketFactory());
+           
+            // Register for port 443 our SSLSocketFactory to the ConnectionManager
+            httpclient.getConnectionManager().getSchemeRegistry().register(scheme);
+           
+        }
+       
+       
+        ClientExecutor executor = new ApacheHttpClient4Executor(httpclient);
+        
+        ResteasyProviderFactory providerFactory = ResteasyProviderFactory.getInstance();
+        providerFactory.addClientErrorInterceptor(new ConfigurationErrorInterceptor());
+        configClient = ProxyFactory.create(SystemConfigurationResource.class, uri, executor, providerFactory);
+    }
+    
+    public ConfigurationResponseData configure(ConfigurationData data) {
+        ConfigurationResponseData response = configClient.configure(data);
+        return response;
+    }
+
+    public InstallToken getInstallToken(InstallTokenRequest data) {
+        InstallToken token = configClient.getInstallToken(data);
+        return token;
+    }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4bcfd66161977f39b2c3cd840f2f1f180217a74
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -0,0 +1,3452 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+ package com.netscape.cms.servlet.csadmin;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.net.ConnectException;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.security.DigestException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.interfaces.RSAPublicKey;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.ParserConfigurationException;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPDN;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv3;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.BadPaddingException;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.IllegalBlockSizeException;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.InvalidKeyFormatException;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.NoSuchItemOnTokenException;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11Store;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.CertBag;
+import org.mozilla.jss.pkcs12.PFX;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs12.SafeBag;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
+import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.Password;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.http.HttpClient;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.HttpResponse;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.ldap.LDAPUtil;
+import com.netscape.cmsutil.xml.XMLObject;
+
+import com.netscape.cms.servlet.csadmin.model.InstallToken;
+import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest;
+
+/**
+ * Utility class for functions to be used both by the RESTful installer
+ * and the UI Panels.
+ * 
+ * @author alee
+ *
+ */
+public class ConfigurationUtils {
+    
+    private static final String PCERT_PREFIX = "preop.cert.";
+    public static String SUCCESS = "0";
+    public static String FAILURE = "1";
+    public static String AUTH_FAILURE = "2";
+    public static final BigInteger BIG_ZERO = new BigInteger("0");
+    public static final Long MINUS_ONE = Long.valueOf(-1);
+    
+    public static boolean loginToken(CryptoToken token, String tokPwd) throws TokenException,
+            IncorrectPasswordException {
+        boolean rv = true;
+        Password password = null;
+        password = new Password(tokPwd.toCharArray());
+
+        if (token.passwordIsInitialized()) {
+            CMS.debug("loginToken():token password is initialized");
+            if (!token.isLoggedIn()) {
+                CMS.debug("loginToken():Token is not logged in, try it");
+                token.login(password);
+            } else {
+                CMS.debug("loginToken():Token has already logged on");
+            }
+        } else {
+            CMS.debug("loginToken():Token password not initialized");
+            rv = false;
+        }
+        return rv;
+    }
+
+    //TODO - replace with Jack's connector code
+    // or as we replace calls with restful calls,  remove altogether
+    public static String getHttpResponse(String hostname, int port, boolean secure,
+            String uri, String content, String clientnickname,
+            SSLCertificateApprovalCallback certApprovalCallback)
+            throws IOException {
+        HttpClient httpclient = null;
+        String c = null;
+
+        try {
+            if (secure) {
+                JssSSLSocketFactory factory = null;
+                if (clientnickname != null && clientnickname.length() > 0)
+                    factory = new JssSSLSocketFactory(clientnickname);
+                else
+                    factory = new JssSSLSocketFactory();
+
+                httpclient = new HttpClient(factory, certApprovalCallback);
+            } else {
+                httpclient = new HttpClient();
+            }
+            httpclient.connect(hostname, port);
+            HttpRequest httprequest = new HttpRequest();
+
+            httprequest.setMethod(HttpRequest.POST);
+            httprequest.setURI(uri);
+            httprequest.setHeader("user-agent", "HTTPTool/1.0");
+            httprequest.setHeader("content-type",
+                    "application/x-www-form-urlencoded");
+            if (content != null && content.length() > 0) {
+                String content_c = content;
+                httprequest.setHeader("content-length", "" + content_c.length());
+                httprequest.setContent(content_c);
+            }
+            HttpResponse httpresponse = httpclient.send(httprequest);
+
+            c = httpresponse.getContent();
+        } catch (ConnectException e) {
+            CMS.debug("getHttpResponse: " + e.toString());
+            throw new IOException("The server you tried to contact is not running.");
+        } catch (Exception e) {
+            CMS.debug("getHttpResponse: " + e.toString());
+            throw new IOException(e.toString());
+        } finally {
+            if (httpclient.connected()) {
+                httpclient.disconnect();
+            }
+        }
+
+        return c;
+    }
+    
+    public static void importCertChain(String host, int port, String serverPath, String tag)
+            throws IOException, SAXException, ParserConfigurationException, CertificateEncodingException,
+            CertificateException, NotInitializedException, TokenException {
+        IConfigStore cs = CMS.getConfigStore();
+        ConfigCertApprovalCallback certApprovalCallback = new ConfigCertApprovalCallback();
+        XMLObject parser = null;
+        String c = ConfigurationUtils.getHttpResponse(host, port, true, serverPath, null, null,
+                certApprovalCallback);
+        if (c != null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            parser = new XMLObject(bis);
+            String certchain = parser.getValue("ChainBase64");
+            if ((certchain != null) && (certchain.length() > 0)) {
+                cs.putString("preop." + tag + ".pkcs7", certchain);
+                CryptoUtil.importCertificateChain(certchain);
+            } else {
+                throw new IOException("importCertChain: Security Domain response does not contain certificate chain");
+            }
+        } else {
+            throw new IOException("importCertChain: Failed to get response from security domain");
+        }
+    }
+    
+    public static String getInstallToken(String sdhost, int sdport, String user, String passwd)
+            throws EPropertyNotFound, EBaseException, URISyntaxException {
+        IConfigStore cs = CMS.getConfigStore();
+        String csType = cs.getString("cs.type");
+
+        InstallTokenRequest data = new InstallTokenRequest(user, passwd, csType, CMS.getEEHost(), CMS.getAdminPort());
+        String baseUri = "https://" + sdhost + ":" + sdport + "/ca/pki";
+        ConfigurationRESTClient client = null;
+        client = new ConfigurationRESTClient(baseUri, null);
+        InstallToken token = client.getInstallToken(data);
+
+        return token.getToken();
+    }
+    
+    public static String getGroupName(String uid, String subsystemname) {
+        IUGSubsystem subsystem = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+        if (subsystem.isMemberOf(uid, "Enterprise CA Administrators") && subsystemname.equals("CA")) {
+            return "Enterprise CA Administrators";
+        } else if (subsystem.isMemberOf(uid, "Enterprise KRA Administrators") && subsystemname.equals("KRA")) {
+            return "Enterprise KRA Administrators";
+        } else if (subsystem.isMemberOf(uid, "Enterprise OCSP Administrators") && subsystemname.equals("OCSP")) {
+            return "Enterprise OCSP Administrators";
+        } else if (subsystem.isMemberOf(uid, "Enterprise TKS Administrators") && subsystemname.equals("TKS")) {
+            return "Enterprise TKS Administrators";
+        } else if (subsystem.isMemberOf(uid, "Enterprise RA Administrators") && subsystemname.equals("RA")) {
+            return "Enterprise RA Administrators";
+        } else if (subsystem.isMemberOf(uid, "Enterprise TPS Administrators") && subsystemname.equals("TPS")) {
+            return "Enterprise TPS Administrators";
+        }
+        return null;
+    }
+    
+    public static String getDomainXML(String hostname, int https_admin_port, boolean https)
+            throws IOException, SAXException, ParserConfigurationException {
+        CMS.debug("getDomainXML start");
+        String c = getHttpResponse(hostname, https_admin_port, https, "/ca/admin/ca/getDomainXML", null, null, null);
+        if (c != null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = null;
+            
+            parser = new XMLObject(bis);
+            String status = parser.getValue("Status");
+            CMS.debug("getDomainXML: status=" + status);
+
+            if (status.equals(SUCCESS)) {
+                String domainInfo = parser.getValue("DomainInfo");
+                CMS.debug("getDomainXML: domainInfo=" + domainInfo);
+                return domainInfo;
+            } else {
+                String error = parser.getValue("Error");
+                throw new IOException(error);
+            }
+
+        }
+        return null;
+    }
+    
+    public static void getSecurityDomainPorts(String domainXML, String host, int port) throws SAXException,
+            IOException, ParserConfigurationException {
+        ByteArrayInputStream bis = new ByteArrayInputStream(domainXML.getBytes());
+        IConfigStore cs = CMS.getConfigStore();
+
+        XMLObject parser = new XMLObject(bis);
+        Document doc = parser.getDocument();
+        NodeList nodeList = doc.getElementsByTagName("CA");
+
+        int len = nodeList.getLength();
+        CMS.debug("len is " + len);
+        for (int i = 0; i < len; i++) {
+            String hostname = parser.getValuesFromContainer(nodeList.item(i), "Host").elementAt(0);
+            String admin_port = parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort").elementAt(0);
+            CMS.debug("hostname: <" + hostname + ">");
+            CMS.debug("admin_port: <" + admin_port + ">");
+
+            if (hostname.equals(host) && admin_port.equals(port + "")) {
+                cs.putString("securitydomain.httpport",
+                        parser.getValuesFromContainer(nodeList.item(i), "UnSecurePort").elementAt(0));
+                cs.putString("securitydomain.httpsagentport",
+                        parser.getValuesFromContainer(nodeList.item(i), "SecureAgentPort").elementAt(0));
+                cs.putString("securitydomain.httpseeport",
+                        parser.getValuesFromContainer(nodeList.item(i), "SecurePort").elementAt(0));
+
+                break;
+            }
+        }
+    }
+    
+    public static Vector<String> getUrlListFromSecurityDomain(IConfigStore config,
+            String type, String portType)
+            throws EPropertyNotFound, EBaseException, IOException, SAXException, ParserConfigurationException {
+        Vector<String> v = new Vector<String>();
+
+        String hostname = config.getString("securitydomain.host");
+        int httpsadminport = config.getInteger("securitydomain.httpsadminport");
+
+        CMS.debug("getUrlListFromSecurityDomain(): Getting domain.xml from CA...");
+        String c = getDomainXML(hostname, httpsadminport, true);
+
+        CMS.debug("getUrlListFromSecurityDomain: Getting " + portType + " from Security Domain ...");
+        if (!portType.equals("UnSecurePort") &&
+                !portType.equals("SecureAgentPort") &&
+                !portType.equals("SecurePort") &&
+                !portType.equals("SecureAdminPort")) {
+            CMS.debug("getUrlListFromSecurityDomain:  " +
+                    "unknown port type " + portType);
+            return v;
+        }
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+        XMLObject parser = new XMLObject(bis);
+        Document doc = parser.getDocument();
+        NodeList nodeList = doc.getElementsByTagName(type);
+
+        // save domain name in cfg
+        config.putString("securitydomain.name", parser.getValue("Name"));
+
+        int len = nodeList.getLength();
+
+        CMS.debug("Len " + len);
+        for (int i = 0; i < len; i++) {
+            Vector<String> v_name = parser.getValuesFromContainer(nodeList.item(i), "SubsystemName");
+            Vector<String> v_host = parser.getValuesFromContainer(nodeList.item(i), "Host");
+            Vector<String> v_port = parser.getValuesFromContainer(nodeList.item(i), portType);
+            Vector<String> v_admin_port = parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort");
+
+            if (v_host.elementAt(0).equals(hostname)
+                    && v_admin_port.elementAt(0).equals(new Integer(httpsadminport).toString())) {
+                // add security domain CA to the beginning of list
+                v.add(0, v_name.elementAt(0) + " - https://" + v_host.elementAt(0) + ":" + v_port.elementAt(0));
+            } else {
+                v.addElement(v_name.elementAt(0) + " - https://" + v_host.elementAt(0) + ":" + v_port.elementAt(0));
+            }
+        }
+
+        return v;
+    }
+    
+    public static boolean isValidCloneURI(String domainXML, String cloneHost, int clonePort) throws EPropertyNotFound,
+            EBaseException, SAXException, IOException, ParserConfigurationException {
+        IConfigStore cs = CMS.getConfigStore();
+        String csType = cs.getString("cs.type");
+        ByteArrayInputStream bis = new ByteArrayInputStream(domainXML.getBytes());
+
+        XMLObject parser = new XMLObject(bis);
+        Document doc = parser.getDocument();
+        NodeList nodeList = doc.getElementsByTagName(csType.toUpperCase());
+
+        int len = nodeList.getLength();
+        for (int i = 0; i < len; i++) {
+            String hostname = parser.getValuesFromContainer(nodeList.item(i), "Host").elementAt(0);
+            String secure_port = parser.getValuesFromContainer(nodeList.item(i), "SecurePort").elementAt(0);
+
+            if (hostname.equals(cloneHost) && secure_port.equals(clonePort + "")) {
+                cs.putString("preop.master.hostname", cloneHost);
+                cs.putInteger("preop.master.httpsport", clonePort);
+                cs.putString("preop.master.httpsadminport",
+                        parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort").elementAt(0));
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static void getConfigEntriesFromMaster()
+            throws IOException, EBaseException, SAXException, ParserConfigurationException {
+
+        IConfigStore config = CMS.getConfigStore();
+        String cstype = "";
+
+        cstype = config.getString("cs.type", "");
+
+        cstype = cstype.toLowerCase();
+
+        String session_id = CMS.getConfigSDSessionId();
+        String master_hostname = "";
+        int master_port = -1;
+        int master_ee_port = -1;
+        master_hostname = config.getString("preop.master.hostname", "");
+        master_port = config.getInteger("preop.master.httpsadminport", -1);
+        master_ee_port = config.getInteger("preop.master.httpsport", -1);
+
+        String content = "";
+        if (cstype.equals("ca") || cstype.equals("kra")) {
+            content = "type=request&xmlOutput=true&sessionID=" + session_id;
+            CMS.debug("http content=" + content);
+            updateNumberRange(master_hostname, master_ee_port, true, content, "request");
+
+            content = "type=serialNo&xmlOutput=true&sessionID=" + session_id;
+            updateNumberRange(master_hostname, master_ee_port, true, content, "serialNo");
+
+            content = "type=replicaId&xmlOutput=true&sessionID=" + session_id;
+            updateNumberRange(master_hostname, master_ee_port, true, content, "replicaId");
+        }
+
+        String list = "";
+
+        list = config.getString("preop.cert.list", "");
+
+        StringBuffer c1 = new StringBuffer();
+        StringBuffer s1 = new StringBuffer();
+        StringTokenizer tok = new StringTokenizer(list, ",");
+        while (tok.hasMoreTokens()) {
+            String t1 = tok.nextToken();
+            if (t1.equals("sslserver"))
+                continue;
+            c1.append(",cloning." + t1 + ".nickname");
+            c1.append(",cloning." + t1 + ".dn");
+            c1.append(",cloning." + t1 + ".keytype");
+            c1.append(",cloning." + t1 + ".keyalgorithm");
+            c1.append(",cloning." + t1 + ".privkey.id");
+            c1.append(",cloning." + t1 + ".pubkey.exponent");
+            c1.append(",cloning." + t1 + ".pubkey.modulus");
+            c1.append(",cloning." + t1 + ".pubkey.encoded");
+
+            if (s1.length() != 0)
+                s1.append(",");
+            s1.append(cstype + "." + t1);
+        }
+
+        if (!cstype.equals("ca")) {
+            c1.append(",cloning.ca.hostname,cloning.ca.httpport,cloning.ca.httpsport,cloning.ca.list,cloning.ca.pkcs7,cloning.ca.type");
+        }
+
+        if (cstype.equals("ca")) {
+            /* get ca connector details */
+            if (s1.length() != 0)
+                s1.append(",");
+            s1.append("ca.connector.KRA");
+        }
+
+        s1.append(",internaldb,internaldb.ldapauth,internaldb.ldapconn");
+
+        content =
+                "op=get&names=cloning.module.token,cloning.token,instanceId,internaldb.basedn,internaldb.ldapauth.password,"
+                        + "internaldb.replication.password" + c1.toString()
+                        + "&substores=" + s1.toString()
+                        + "&xmlOutput=true&sessionID="
+                        + session_id;
+        boolean success = updateConfigEntries(master_hostname, master_port, true,
+                "/" + cstype + "/admin/" + cstype + "/getConfigEntries", content, config);
+        if (!success) {
+            throw new IOException("Failed to get configuration entries from the master");
+        }
+        config.putString("preop.clone.configuration", "true");
+
+        config.commit(false);
+
+    }
+    
+    public static void updateNumberRange(String hostname, int port, boolean https, String content, String type)
+            throws IOException, EBaseException, SAXException, ParserConfigurationException {
+        CMS.debug("updateNumberRange start host=" + hostname + " port=" + port);
+        IConfigStore cs = CMS.getConfigStore();
+
+        String cstype = "";
+        cstype = cs.getString("cs.type", "");
+        cstype = cstype.toLowerCase();
+
+        String serverPath = "/" + cstype + "/ee/" + cstype + "/updateNumberRange";
+        String c = getHttpResponse(hostname, port, https, serverPath, content, null, null);
+        if (c == null || c.equals("")) {
+            CMS.debug("updateNumberRange: content is null.");
+            throw new IOException("The server you want to contact is not available");
+        } else {
+            CMS.debug("content=" + c);
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = null;
+            parser = new XMLObject(bis);
+            String status = parser.getValue("Status");
+
+            CMS.debug("updateNumberRange(): status=" + status);
+            if (status.equals(SUCCESS)) {
+                String beginNum = parser.getValue("beginNumber");
+                String endNum = parser.getValue("endNumber");
+                if (type.equals("request")) {
+                    cs.putString("dbs.beginRequestNumber", beginNum);
+                    cs.putString("dbs.endRequestNumber", endNum);
+                } else if (type.equals("serialNo")) {
+                    cs.putString("dbs.beginSerialNumber", beginNum);
+                    cs.putString("dbs.endSerialNumber", endNum);
+                } else if (type.equals("replicaId")) {
+                    cs.putString("dbs.beginReplicaNumber", beginNum);
+                    cs.putString("dbs.endReplicaNumber", endNum);
+                }
+                // enable serial number management in clone
+                cs.putString("dbs.enableSerialManagement", "true");
+                cs.commit(false);
+                return;
+            } else if (status.equals(AUTH_FAILURE)) {
+                throw new EAuthException(AUTH_FAILURE);
+            } else {
+                String error = parser.getValue("Error");
+                throw new IOException(error);
+            }
+        }
+    }
+    
+    public static boolean updateConfigEntries(String hostname, int port, boolean https,
+            String servlet, String uri, IConfigStore config) 
+                    throws IOException, EBaseException, SAXException, ParserConfigurationException {
+        CMS.debug("updateConfigEntries start");
+        String c = getHttpResponse(hostname, port, https, servlet, uri, null, null);
+
+        if (c != null) {
+
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = null;
+
+            parser = new XMLObject(bis);
+
+            String status = parser.getValue("Status");
+            CMS.debug("updateConfigEntries: status=" + status);
+
+            if (status.equals(SUCCESS)) {
+                String cstype = "";
+
+                cstype = config.getString("cs.type", "");
+
+                Document doc = parser.getDocument();
+                NodeList list = doc.getElementsByTagName("name");
+                int len = list.getLength();
+                for (int i = 0; i < len; i++) {
+                    Node n = list.item(i);
+                    NodeList nn = n.getChildNodes();
+                    String name = nn.item(0).getNodeValue();
+                    Node parent = n.getParentNode();
+                    nn = parent.getChildNodes();
+                    int len1 = nn.getLength();
+                    String v = "";
+                    for (int j = 0; j < len1; j++) {
+                        Node nv = nn.item(j);
+                        String val = nv.getNodeName();
+                        if (val.equals("value")) {
+                            NodeList n2 = nv.getChildNodes();
+                            if (n2.getLength() > 0)
+                                v = n2.item(0).getNodeValue();
+                            break;
+                        }
+                    }
+
+                    if (name.equals("internaldb.basedn")) {
+                        config.putString(name, v);
+                        config.putString("preop.internaldb.master.basedn", v);
+                    } else if (name.startsWith("internaldb")) {
+                        config.putString(name.replaceFirst("internaldb", "preop.internaldb.master"), v);
+                    } else if (name.equals("instanceId")) {
+                        config.putString("preop.master.instanceId", v);
+                    } else if (name.equals("cloning.signing.nickname")) {
+                        config.putString("preop.master.signing.nickname", v);
+                        config.putString("preop.cert.signing.nickname", v);
+                    } else if (name.equals("cloning.ocsp_signing.nickname")) {
+                        config.putString("preop.master.ocsp_signing.nickname", v);
+                        config.putString("preop.cert.ocsp_signing.nickname", v);
+                    } else if (name.equals("cloning.subsystem.nickname")) {
+                        config.putString("preop.master.subsystem.nickname", v);
+                        config.putString("preop.cert.subsystem.nickname", v);
+                    } else if (name.equals("cloning.transport.nickname")) {
+                        config.putString("preop.master.transport.nickname", v);
+                        config.putString("kra.transportUnit.nickName", v);
+                        config.putString("preop.cert.transport.nickname", v);
+                    } else if (name.equals("cloning.storage.nickname")) {
+                        config.putString("preop.master.storage.nickname", v);
+                        config.putString("kra.storageUnit.nickName", v);
+                        config.putString("preop.cert.storage.nickname", v);
+                    } else if (name.equals("cloning.audit_signing.nickname")) {
+                        config.putString("preop.master.audit_signing.nickname", v);
+                        config.putString("preop.cert.audit_signing.nickname", v);
+                        config.putString(name, v);
+                    } else if (name.startsWith("cloning.ca")) {
+                        config.putString(name.replaceFirst("cloning", "preop"), v);
+                    } else if (name.equals("cloning.signing.keyalgorithm")) {
+                        config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+                        if (cstype.equals("CA")) {
+                            config.putString("ca.crl.MasterCRL.signingAlgorithm", v);
+                            config.putString("ca.signing.defaultSigningAlgorithm", v);
+                        } else if (cstype.equals("OCSP")) {
+                            config.putString("ocsp.signing.defaultSigningAlgorithm", v);
+                        }
+                    } else if (name.equals("cloning.transport.keyalgorithm")) {
+                        config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+                        config.putString("kra.transportUnit.signingAlgorithm", v);
+                    } else if (name.equals("cloning.ocsp_signing.keyalgorithm")) {
+                        config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+                        if (cstype.equals("CA")) {
+                            config.putString("ca.ocsp_signing.defaultSigningAlgorithm", v);
+                        }
+                    } else if (name.startsWith("cloning")) {
+                        config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+                    } else {
+                        config.putString(name, v);
+                    }
+                }
+
+                // set master ldap password (if it exists) temporarily in password store
+                // in case it is needed for replication.  Not stored in password.conf.
+
+                String master_pwd = config.getString("preop.internaldb.master.ldapauth.password", "");
+                if (!master_pwd.equals("")) {
+                    config.putString("preop.internaldb.master.ldapauth.bindPWPrompt", "master_internaldb");
+                    String passwordFile = config.getString("passwordFile");
+                    IConfigStore psStore = CMS.createFileConfigStore(passwordFile);
+                    psStore.putString("master_internaldb", master_pwd);
+                    psStore.commit(false);
+                }
+
+                return true;
+            } else if (status.equals(AUTH_FAILURE)) {
+                throw new EAuthException(AUTH_FAILURE);
+            } else {
+                String error = parser.getValue("Error");
+                throw new IOException(error);
+            }
+        }
+
+        return false;
+    }
+    
+    public static void restoreCertsFromP12(String p12File, String p12Pass) throws EPropertyNotFound, EBaseException,
+            InvalidKeyException, CertificateException, NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException, IllegalStateException, TokenException, IllegalBlockSizeException,
+            BadPaddingException, NotInitializedException, NicknameConflictException, UserCertConflictException,
+            NoSuchItemOnTokenException, InvalidBERException, IOException {
+        byte b[] = new byte[1000000];
+        IConfigStore cs = CMS.getConfigStore();
+        String instanceRoot = cs.getString("instanceRoot");
+
+        FileInputStream fis = new FileInputStream(instanceRoot + "/alias/" + p12File);
+        while (fis.available() > 0)
+            fis.read(b);
+        fis.close();
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(b);
+        StringBuffer reason = new StringBuffer();
+        Password password = new Password(p12Pass.toCharArray());
+        PFX pfx = null;
+        boolean verifypfx = false;
+
+        pfx = (PFX) (new PFX.Template()).decode(bis);
+        verifypfx = pfx.verifyAuthSafes(password, reason);
+
+        if (verifypfx) {
+            AuthenticatedSafes safes = pfx.getAuthSafes();
+            Vector<Vector<Object>> pkeyinfo_collection = new Vector<Vector<Object>>();
+            Vector<Vector<Object>> cert_collection = new Vector<Vector<Object>>();
+            for (int i = 0; i < safes.getSize(); i++) {
+                SEQUENCE scontent = safes.getSafeContentsAt(null, i);
+                for (int j = 0; j < scontent.size(); j++) {
+                    SafeBag bag = (SafeBag) scontent.elementAt(j);
+                    OBJECT_IDENTIFIER oid = bag.getBagType();
+                    if (oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) {
+                        EncryptedPrivateKeyInfo privkeyinfo =
+                                (EncryptedPrivateKeyInfo) bag.getInterpretedBagContent();
+                        PrivateKeyInfo pkeyinfo = privkeyinfo.decrypt(password, new PasswordConverter());
+                        Vector<Object> pkeyinfo_v = new Vector<Object>();
+                        pkeyinfo_v.addElement(pkeyinfo);
+                        SET bagAttrs = bag.getBagAttributes();
+                        for (int k = 0; k < bagAttrs.size(); k++) {
+                            Attribute attrs = (Attribute) bagAttrs.elementAt(k);
+                            OBJECT_IDENTIFIER aoid = attrs.getType();
+                            if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
+                                SET val = attrs.getValues();
+                                ANY ss = (ANY) val.elementAt(0);
+                                ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
+                                BMPString sss = (BMPString) new BMPString.Template().decode(bbis);
+                                String s = sss.toString();
+                                pkeyinfo_v.addElement(s);
+                            }
+                        }
+                        pkeyinfo_collection.addElement(pkeyinfo_v);
+                    } else if (oid.equals(SafeBag.CERT_BAG)) {
+                        CertBag cbag = (CertBag) bag.getInterpretedBagContent();
+                        OCTET_STRING str = (OCTET_STRING) cbag.getInterpretedCert();
+                        byte[] x509cert = str.toByteArray();
+                        Vector<Object> cert_v = new Vector<Object>();
+                        cert_v.addElement(x509cert);
+                        SET bagAttrs = bag.getBagAttributes();
+
+                        if (bagAttrs != null) {
+                            for (int k = 0; k < bagAttrs.size(); k++) {
+                                Attribute attrs = (Attribute) bagAttrs.elementAt(k);
+                                OBJECT_IDENTIFIER aoid = attrs.getType();
+                                if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
+                                    SET val = attrs.getValues();
+                                    ANY ss = (ANY) val.elementAt(0);
+                                    ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
+                                    BMPString sss = (BMPString) (new BMPString.Template()).decode(bbis);
+                                    String s = sss.toString();
+                                    cert_v.addElement(s);
+                                }
+                            }
+                        }
+
+                        cert_collection.addElement(cert_v);
+                    }
+                }
+            }
+
+            importkeycert(pkeyinfo_collection, cert_collection);
+        } else {
+            throw new IOException("P12 File is incorrect");
+        }
+
+    }
+    
+    public static boolean isCertdbCloned() {
+        IConfigStore cs = CMS.getConfigStore();
+        try {
+            CryptoManager cm = CryptoManager.getInstance();
+            String certList = cs.getString("preop.cert.list");
+            String cstype = cs.getString("cs.type").toLowerCase();
+            StringTokenizer st = new StringTokenizer(certList, ",");
+            while (st.hasMoreTokens()) {
+                String tag = st.nextToken();
+                if (tag.equals("sslserver"))
+                    continue;
+                String tokenname = cs.getString("preop.module.token", "");
+                cm.getTokenByName(tokenname); // throw exception if token doesn't exist
+                String name1 = "preop.master." + tag + ".nickname";
+                String nickname = cs.getString(name1, "");
+                if (!tokenname.equals("Internal Key Storage Token") &&
+                        !tokenname.equals("internal"))
+                    nickname = tokenname + ":" + nickname;
+
+                CMS.debug("isCertdbCloned: " + nickname);
+                
+                // TODO : remove this when we eliminate the extraneous nicknames
+                // needed for self tests  
+                cs.putString(cstype + ".cert." + tag + ".nickname", nickname);
+                
+                X509Certificate cert = cm.findCertByNickname(nickname);
+                if (cert == null)
+                    return false;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+
+        return true;
+    }
+    
+    public static void importkeycert(Vector<Vector<Object>> pkeyinfo_collection,
+            Vector<Vector<Object>> cert_collection) throws IOException, CertificateException, TokenException,
+            NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalStateException,
+            IllegalBlockSizeException, BadPaddingException, NotInitializedException, NicknameConflictException,
+            UserCertConflictException, NoSuchItemOnTokenException, EPropertyNotFound, EBaseException {
+        CryptoManager cm = CryptoManager.getInstance();
+        
+        // delete all existing certificates first
+        deleteExistingCerts();
+
+        for (int i = 0; i < pkeyinfo_collection.size(); i++) {
+            Vector<Object> pkeyinfo_v = pkeyinfo_collection.elementAt(i);
+            PrivateKeyInfo pkeyinfo = (PrivateKeyInfo) pkeyinfo_v.elementAt(0);
+            String nickname = (String) pkeyinfo_v.elementAt(1);
+            byte[] x509cert = getX509Cert(nickname, cert_collection);
+            X509Certificate cert = cm.importCACertPackage(x509cert);
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            pkeyinfo.encode(bos);
+            byte[] pkey = bos.toByteArray();
+
+            PublicKey publickey = cert.getPublicKey();
+            CryptoToken token = cm.getInternalKeyStorageToken();
+            CryptoStore store = token.getCryptoStore();
+
+            try {
+                store.deleteCert(cert);
+            } catch (NoSuchItemOnTokenException e) {
+                // this is OK
+            }
+
+            KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3);
+            SymmetricKey sk = kg.generate();
+            byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+            IVParameterSpec param = new IVParameterSpec(iv);
+            Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+            c.initEncrypt(sk, param);
+            byte[] encpkey = c.doFinal(pkey);
+
+            KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+            wrapper.initUnwrap(sk, param);
+            wrapper.unwrapPrivate(encpkey, getPrivateKeyType(publickey), publickey);
+
+        }
+
+        for (int i = 0; i < cert_collection.size(); i++) {
+
+            Vector<Object> cert_v = cert_collection.elementAt(i);
+            byte[] cert = (byte[]) cert_v.elementAt(0);
+            if (cert_v.size() > 1) {
+                String name = (String) cert_v.elementAt(1);
+                // we need to delete the trusted CA certificate if it is
+                // the same as the ca signing certificate
+                if (isCASigningCert(name)) {
+                    X509Certificate certchain = getX509CertFromToken(cert);
+                    if (certchain != null) {
+                        CryptoToken token = cm.getInternalKeyStorageToken();
+                        CryptoStore store = token.getCryptoStore();
+                        if (store instanceof PK11Store) {
+                            try {
+                                PK11Store pk11store = (PK11Store) store;
+                                pk11store.deleteCertOnly(certchain);
+                            } catch (Exception ee) {
+                                CMS.debug("importKeyCert: Exception=" + ee.toString());
+                            }
+                        }
+                    }
+                }
+
+                X509Certificate xcert = cm.importUserCACertPackage(cert, name);
+                if (isCASigningCert(name)) {
+                    // we need to change the trust attribute to CT
+                    InternalCertificate icert = (InternalCertificate) xcert;
+                    icert.setSSLTrust(InternalCertificate.TRUSTED_CA
+                            | InternalCertificate.TRUSTED_CLIENT_CA
+                            | InternalCertificate.VALID_CA);
+                } else if (isAuditSigningCert(name)) {
+                    InternalCertificate icert = (InternalCertificate) xcert;
+                    icert.setObjectSigningTrust(InternalCertificate.USER
+                            | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER);
+                }
+            } else {
+                cm.importCACertPackage(cert);
+            }
+        }
+    }
+
+    public static X509Certificate getX509CertFromToken(byte[] cert)
+            throws IOException, CertificateException, NotInitializedException {
+
+        X509CertImpl impl = new X509CertImpl(cert);
+        String issuer_impl = impl.getIssuerDN().toString();
+        BigInteger serial_impl = impl.getSerialNumber();
+        CryptoManager cm = CryptoManager.getInstance();
+        X509Certificate[] permcerts = cm.getPermCerts();
+        for (int i = 0; i < permcerts.length; i++) {
+            String issuer_p = permcerts[i].getSubjectDN().toString();
+            BigInteger serial_p = permcerts[i].getSerialNumber();
+            if (issuer_p.equals(issuer_impl) && serial_p.compareTo(serial_impl) == 0) {
+                return permcerts[i];
+            }
+        }
+        return null;
+    }
+    
+    public static org.mozilla.jss.crypto.PrivateKey.Type getPrivateKeyType(PublicKey pubkey) {
+        CMS.debug("Key Algorithm '" + pubkey.getAlgorithm() + "'");
+        if (pubkey.getAlgorithm().equals("EC")) {
+            return org.mozilla.jss.crypto.PrivateKey.Type.EC;
+        }
+        return org.mozilla.jss.crypto.PrivateKey.Type.RSA;
+    }
+    
+    public static boolean isCASigningCert(String name) {
+        IConfigStore cs = CMS.getConfigStore();
+        try {
+            String nickname = cs.getString("preop.master.signing.nickname");
+            if (nickname.equals(name)) return true;
+        } catch(Exception e) {
+            // nickname may not exist if this is not cloning a CA
+        };
+        
+        return false;
+    }
+    
+    public static boolean isAuditSigningCert(String name) throws EPropertyNotFound, EBaseException {
+        IConfigStore cs = CMS.getConfigStore();
+        String nickname = cs.getString("preop.master.audit_signing.nickname");
+        if (nickname.equals(name)) return true;
+        return false;
+    }
+    
+    public static void deleteExistingCerts() {
+        IConfigStore cs = CMS.getConfigStore();
+        try {
+            String list = cs.getString("preop.cert.list", "");
+            StringTokenizer st = new StringTokenizer(list, ",");
+            while (st.hasMoreTokens()) {
+                String s = st.nextToken();
+                if (s.equals("sslserver"))
+                    continue;
+                String name = "preop.master." + s + ".nickname";
+                String nickname = cs.getString(name, "");
+                CryptoManager cm = CryptoManager.getInstance();
+                X509Certificate xcert = null;
+                try {
+                    xcert = cm.findCertByNickname(nickname);
+                } catch (Exception ee) {
+                    CMS.debug("deleteExistingCerts: Exception=" + ee.toString());
+                }
+                CryptoToken ct = cm.getInternalKeyStorageToken();
+                CryptoStore store = ct.getCryptoStore();
+                try {
+                    store.deleteCert(xcert);
+                } catch (Exception ee) {
+                    CMS.debug("deleteExistingCerts: Exception=" + ee.toString());
+                }
+            }
+        } catch (Exception e) {
+            CMS.debug("deleteExistingCerts: Exception=" + e.toString());
+        }
+    }
+    
+    public static byte[] getX509Cert(String nickname, Vector<Vector<Object>> cert_collection)
+            throws CertificateException {
+        for (int i = 0; i < cert_collection.size(); i++) {
+            Vector<Object> v = cert_collection.elementAt(i);
+            byte[] b = (byte[]) v.elementAt(0);
+            X509CertImpl impl = null;
+            impl = new X509CertImpl(b);
+            Principal subjectdn = impl.getSubjectDN();
+            if (LDAPDN.equals(subjectdn.toString(), nickname)) return b;
+        }
+        return null;
+    }
+    
+    public static void releaseConnection(LDAPConnection conn) {
+        try {
+            if (conn != null) conn.disconnect();
+        } catch (LDAPException e) {
+            e.printStackTrace();
+            CMS.debug("releaseConnection: " + e);
+        }
+    }
+    
+    public static void populateDB() throws IOException, EBaseException {
+        IConfigStore cs = CMS.getConfigStore();
+               
+        String baseDN = cs.getString("internaldb.basedn");
+        String database = cs.getString("internaldb.database", "");
+        String remove = cs.getString("preop.database.removeData", "false");
+        
+        IConfigStore dbCfg = cs.getSubStore("internaldb");
+        ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory();
+        dbFactory.init(dbCfg);
+        LDAPConnection conn = dbFactory.getConn();
+
+        // check that the database and baseDN do not exist
+        boolean foundBaseDN = false;
+        try {
+            LDAPEntry entry = conn.read(baseDN);
+            if (entry != null) foundBaseDN = true;
+        } catch (LDAPException e) {
+            switch (e.getLDAPResultCode()) {
+            case LDAPException.NO_SUCH_OBJECT:
+                break;
+            default:
+                e.printStackTrace();
+                CMS.debug("populateDB: LDAPException " + e.toString());
+                releaseConnection(conn);
+                throw new IOException("Failed to determine if basedDN exists.");
+            }
+        }
+
+        boolean foundDatabase = false;
+        try {
+            String dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config";
+            LDAPEntry entry = conn.read(dn);
+            if (entry != null) foundDatabase = true;
+        } catch (LDAPException e) {
+            switch (e.getLDAPResultCode()) {
+            case LDAPException.NO_SUCH_OBJECT:
+                break;
+            default:
+                e.printStackTrace();
+                CMS.debug("populatedb: LDAPException " + e.toString());
+                releaseConnection(conn);
+                throw new IOException("Failed to determine if database exists.");
+            }
+        }
+        try {
+            String dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config";
+            LDAPEntry entry = conn.read(dn);
+            if (entry != null) foundDatabase = true;
+        } catch (LDAPException e) {
+            switch (e.getLDAPResultCode()) {
+            case LDAPException.NO_SUCH_OBJECT:
+                break;
+            default:
+                e.printStackTrace();
+                CMS.debug("populateDB: LDAPException " + e.toString());
+                releaseConnection(conn);
+                throw new IOException("Failed to determine if mapping tree exists.");
+            }
+        }
+
+        if (foundDatabase) {
+            CMS.debug("populatedb: This database has already been used.");
+            if (remove.equals("false")) {
+                releaseConnection(conn);
+                throw new IOException("This database has already been used. " +
+                		"Select the checkbox below to remove all data and reuse this database");
+            } else {
+                CMS.debug("populateDB: Deleting existing DB and reusing base DN");
+                cleanupDB(conn, baseDN, database);
+                foundBaseDN = false;
+                foundDatabase = false;
+            }
+        }
+
+        if (foundBaseDN) {
+            CMS.debug("DatabasePanel update: This base DN has already been used.");
+            if (remove.equals("false")) {
+                releaseConnection(conn);
+                throw new IOException( "This base DN (" + baseDN
+                        + ") has already been used. Select the checkbox below to remove all data and reuse this base DN");
+            } else {
+                CMS.debug("populateDB: Deleting existing DB and reusing base DN");
+                cleanupDB(conn, baseDN, database);
+                foundBaseDN = false;
+                foundDatabase = false;
+            }
+        }
+
+        // create database
+        try {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            String oc[] = { "top", "extensibleObject", "nsBackendInstance" };
+            attrs.add(new LDAPAttribute("objectClass", oc));
+            attrs.add(new LDAPAttribute("cn", database));
+            attrs.add(new LDAPAttribute("nsslapd-suffix", baseDN));
+            String dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config";
+            LDAPEntry entry = new LDAPEntry(dn, attrs);
+            conn.add(entry);
+        } catch (Exception e) {
+            CMS.debug("populateDB: Warning: database creation error - " + e.toString());
+            releaseConnection(conn);
+            throw new IOException("Failed to create the database.");
+        }
+
+        try {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            String oc2[] = { "top", "extensibleObject", "nsMappingTree" };
+            attrs.add(new LDAPAttribute("objectClass", oc2));
+            attrs.add(new LDAPAttribute("cn", baseDN));
+            attrs.add(new LDAPAttribute("nsslapd-backend", database));
+            attrs.add(new LDAPAttribute("nsslapd-state", "Backend"));
+            String dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config";
+            LDAPEntry entry = new LDAPEntry(dn, attrs);
+            conn.add(entry);
+        } catch (Exception e) {
+            CMS.debug("populateDB: Warning: database mapping tree creation error - " + e.toString());
+            releaseConnection(conn);
+            throw new IOException("Failed to create the database.");
+        }
+
+        try {
+            // create base dn
+            CMS.debug("Creating base DN: " + baseDN);
+            String dns3[] = LDAPDN.explodeDN(baseDN, false);
+            StringTokenizer st = new StringTokenizer(dns3[0], "=");
+            String n = st.nextToken();
+            String v = st.nextToken();
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            String oc3[] = { "top", "domain" };
+            if (n.equals("o")) {
+                oc3[1] = "organization";
+            } else if (n.equals("ou")) {
+                oc3[1] = "organizationalUnit";
+            }
+            attrs.add(new LDAPAttribute("objectClass", oc3));
+            attrs.add(new LDAPAttribute(n, v));
+
+            LDAPEntry entry = new LDAPEntry(baseDN, attrs);
+            conn.add(entry);
+        } catch (Exception e) {
+            CMS.debug("populateDB: Warning: suffix creation error - " + e.toString());
+            releaseConnection(conn);
+            throw new IOException("Failed to create the base DN: " + baseDN);
+        }
+
+        try {
+            String select = cs.getString("preop.subsystem.select", "");
+            if (select.equals("clone")) {
+                // if this is clone, add index before replication
+                // don't put in the schema or bad things will happen
+                importLDIFS("preop.internaldb.ldif", conn);
+                importLDIFS("preop.internaldb.index_ldif", conn);
+                importLDIFS("preop.internaldb.manager_ldif", conn);
+            } else {
+                // data will be replicated from the master to the clone
+                // so clone does not need the data
+                importLDIFS("preop.internaldb.schema.ldif", conn);
+                importLDIFS("preop.internaldb.ldif", conn);
+                importLDIFS("preop.internaldb.data_ldif", conn);
+                importLDIFS("preop.internaldb.index_ldif", conn);
+                importLDIFS("preop.internaldb.manager_ldif", conn);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            CMS.debug("Failed to import ldif files" + e);
+            releaseConnection(conn);
+            throw new IOException("Failed to import ldif files");
+        }
+        
+        releaseConnection(conn);
+    }
+
+    public static void importLDIFS(String param, LDAPConnection conn) throws IOException, EPropertyNotFound,
+            EBaseException {
+        IConfigStore cs = CMS.getConfigStore();
+
+        CMS.debug("importLDIFS: param=" + param);
+        String v = cs.getString(param);
+
+        String baseDN = cs.getString("internaldb.basedn");
+        String database = cs.getString("internaldb.database");
+        String instancePath = cs.getString("instanceRoot");
+        String instanceId = cs.getString("instanceId");
+        String dbuser = "uid=" + cs.getString("cs.type") + "-" + cs.getString("machineName") + "-"
+                + cs.getString("service.securePort") + ",ou=people," + baseDN;
+        String configDir = instancePath + File.separator + "conf";
+
+        StringTokenizer tokenizer = new StringTokenizer(v, ",");
+        while (tokenizer.hasMoreTokens()) {
+            String token = tokenizer.nextToken().trim();
+            int index = token.lastIndexOf("/");
+            String name = token;
+
+            if (index != -1) {
+                name = token.substring(index + 1);
+            }
+
+            CMS.debug("importLDIFS(): ldif file = " + token);
+            String filename = configDir + File.separator + name;
+
+            CMS.debug("importLDIFS(): ldif file copy to " + filename);
+            PrintStream ps = null;
+            BufferedReader in = null;
+
+            in = new BufferedReader(new FileReader(token));
+            ps = new PrintStream(new FileOutputStream(filename, false));
+            while (in.ready()) {
+                String s = in.readLine();
+                int n = s.indexOf("{");
+
+                if (n == -1) {
+                    ps.println(s);
+                } else {
+                    boolean endOfline = false;
+
+                    while (n != -1) {
+                        ps.print(s.substring(0, n));
+                        int n1 = s.indexOf("}");
+                        String tok = s.substring(n + 1, n1);
+
+                        if (tok.equals("instanceId")) {
+                            ps.print(instanceId);
+                        } else if (tok.equals("rootSuffix")) {
+                            ps.print(baseDN);
+                        } else if (tok.equals("database")) {
+                            ps.print(database);
+                        } else if (tok.equals("dbuser")) {
+                            ps.print(dbuser);
+                        }
+                        if ((s.length() + 1) == n1) {
+                            endOfline = true;
+                            break;
+                        }
+                        s = s.substring(n1 + 1);
+                        n = s.indexOf("{");
+                    }
+
+                    if (!endOfline) {
+                        ps.println(s);
+                    }
+                }
+            }
+            in.close();
+            ps.close();
+
+            ArrayList<String> errors = new ArrayList<String>();
+            LDAPUtil.importLDIF(conn, filename, errors);
+            if (!errors.isEmpty()) {
+                CMS.debug("importLDIFS(): LDAP Errors in importing " + filename);
+                for (String error : errors) {
+                    CMS.debug(error);
+                }
+            }
+        }
+    }
+    
+    public static void cleanupDB(LDAPConnection conn, String baseDN, String database) {
+        String[] entries = {};
+        String filter = "objectclass=*";
+        LDAPSearchConstraints cons = null;
+        String[] attrs = null;
+        String dn = "";
+        try {
+            CMS.debug("cleanupDB: Deleting baseDN: " + baseDN);
+            LDAPSearchResults res = conn.search(baseDN, LDAPConnection.SCOPE_BASE, filter,
+                    attrs, true, cons);
+            if (res != null)
+                deleteEntries(res, conn, baseDN, entries);
+        } catch (LDAPException e) {
+            CMS.debug("cleanupDB: ldapexception thrown" + e);
+        }
+
+        try {
+            dn = "cn=mapping tree, cn=config";
+            filter = "nsslapd-backend=" + database;
+            LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_ONE, filter,
+                    attrs, true, cons);
+            if (res != null) {
+                while (res.hasMoreElements()) {
+                    dn = res.next().getDN();
+                    filter = "objectclass=*";
+                    LDAPSearchResults res2 = conn.search(dn, LDAPConnection.SCOPE_BASE, filter,
+                            attrs, true, cons);
+                    if (res2 != null)
+                        deleteEntries(res2, conn, dn, entries);
+                }
+            }
+        } catch (LDAPException e) {
+            CMS.debug("cleanupDB: ldapexception thrown" + e);
+        }
+
+        try {
+            dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config";
+            LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_BASE, filter,
+                    attrs, true, cons);
+            if (res != null) {
+                deleteEntries(res, conn, dn, entries);
+                String dbdir = getInstanceDir(conn) + "/db/" + database;
+                if (dbdir != null) {
+                    CMS.debug("cleanupDB: Deleting dbdir " + dbdir);
+                    boolean success = deleteDir(new File(dbdir));
+                    if (!success) {
+                        CMS.debug("cleanupDB: Unable to delete database directory " + dbdir);
+                    }
+                }
+            }
+        } catch (LDAPException e) {
+            CMS.debug("cleanupDB: ldapexception thrown" + e);
+        }
+    }
+    
+    public static void deleteEntries(LDAPSearchResults res, LDAPConnection conn,
+            String dn, String[] entries) {
+        String[] attrs = null;
+        LDAPSearchConstraints cons = null;
+        String filter = "objectclass=*";
+
+        try {
+            if (res.getCount() == 0)
+                return;
+            else {
+                while (res.hasMoreElements()) {
+                    LDAPEntry entry = res.next();
+                    String dn1 = entry.getDN();
+                    LDAPSearchResults res1 = conn.search(dn1, 1, filter, attrs, true, cons);
+                    deleteEntries(res1, conn, dn1, entries);
+                    deleteEntry(conn, dn1, entries);
+                }
+            }
+        } catch (Exception ee) {
+            CMS.debug("deleteEntries: Exception=" + ee.toString());
+        }
+    }
+
+    public static void deleteEntry(LDAPConnection conn, String dn, String[] entries) {
+        try {
+            for (int i = 0; i < entries.length; i++) {
+                if (LDAPDN.equals(dn, entries[i])) {
+                    CMS.debug("deleteEntry: entry with this dn " + dn + " is not deleted.");
+                    return;
+                }
+            }
+
+            CMS.debug("deleteEntry: deleting dn=" + dn);
+            conn.delete(dn);
+        } catch (Exception e) {
+            CMS.debug("deleteEntry: Exception=" + e.toString());
+        }
+    }
+    
+    public static String getInstanceDir(LDAPConnection conn) throws LDAPException {
+        String instancedir = "";
+
+        String filter = "(objectclass=*)";
+        String[] attrs = { "nsslapd-directory" };
+        LDAPSearchResults results = conn.search("cn=config,cn=ldbm database,cn=plugins,cn=config", 
+                LDAPv3.SCOPE_SUB, filter, attrs, false);
+
+        while (results.hasMoreElements()) {
+            LDAPEntry entry = results.next();
+            String dn = entry.getDN();
+            CMS.debug("getInstanceDir: DN for storing nsslapd-directory: " + dn);
+            LDAPAttributeSet entryAttrs = entry.getAttributeSet();
+            
+            @SuppressWarnings("unchecked")
+            Enumeration<LDAPAttribute> attrsInSet = entryAttrs.getAttributes();
+            while (attrsInSet.hasMoreElements()) {
+                LDAPAttribute nextAttr = attrsInSet.nextElement();
+                String attrName = nextAttr.getName();
+                CMS.debug("getInstanceDir: attribute name: " + attrName);
+                @SuppressWarnings("unchecked")
+                Enumeration<String> valsInAttr = nextAttr.getStringValues();
+                while (valsInAttr.hasMoreElements()) {
+                    String nextValue = valsInAttr.nextElement();
+                    if (attrName.equalsIgnoreCase("nsslapd-directory")) {
+                        CMS.debug("getInstanceDir: instanceDir=" + nextValue);
+                        return nextValue.substring(0, nextValue.lastIndexOf("/db"));
+                    }
+                }
+            }
+        }
+
+        return instancedir;
+    }
+    
+    public static boolean deleteDir(File dir) {
+        if (dir.isDirectory()) {
+            String[] children = dir.list();
+            for (int i = 0; i < children.length; i++) {
+                boolean success = deleteDir(new File(dir, children[i]));
+                if (!success) {
+                    return false;
+                }
+            }
+        }
+        return dir.delete();
+    }
+     
+    public static void populateIndexes() throws EPropertyNotFound, EBaseException, IOException, LDAPException {
+        CMS.debug("populateIndexes(): start");
+        IConfigStore cs = CMS.getConfigStore();
+
+        IConfigStore dbCfg = cs.getSubStore("internaldb");
+        ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory();
+        dbFactory.init(dbCfg);
+        LDAPConnection conn = dbFactory.getConn();
+
+        try {
+            importLDIFS("preop.internaldb.post_ldif", conn);
+
+            /* For vlvtask, we need to check if the task has 
+               been completed or not.  Presence of nsTaskExitCode means task is complete
+             */
+            String wait_dn = cs.getString("preop.internaldb.wait_dn", "");
+            if (!wait_dn.equals("")) {
+                LDAPEntry task = null;
+                boolean taskComplete = false;
+                CMS.debug("Checking wait_dn " + wait_dn);
+                do {
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        // restore the interrupted status
+                        Thread.currentThread().interrupt();
+                    }
+                    
+                    try {
+                        task = conn.read(wait_dn, (String[]) null);
+                        if (task != null) {
+                            LDAPAttribute attr = task.getAttribute("nsTaskExitCode");
+                            if (attr != null) {
+                                taskComplete = true;
+                                String val = (String) attr.getStringValues().nextElement();
+                                if (val.compareTo("0") != 0) {
+                                    CMS.debug("Error in populating local indexes: nsTaskExitCode=" + val);
+                                }
+                            }
+                        }
+                    } catch (Exception le) {
+                        CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + le.toString() + ")");
+                    }  
+                } while (!taskComplete);            
+            }
+        } catch (Exception e) {
+            CMS.debug("populateIndexes(): Exception thrown: " + e);
+            throw e;
+        } finally {
+            releaseConnection(conn);
+        }
+    }
+    
+    public static void setupReplication() throws EBaseException, IOException {
+        IConfigStore cs = CMS.getConfigStore();
+
+        String machinename = cs.getString("machineName", "");
+        String instanceId = cs.getString("instanceId", "");
+        String secure = cs.getString("internaldb.ldapconn.secureConn");
+        String replicationSecurity = cs.getString("internaldb.ldapconn.replicationSecurity");
+        int masterReplicationPort = cs.getInteger("internaldb.ldapconn.masterReplicationPort");
+        int cloneReplicationPort = cs.getInteger("internaldb.ldapconn.cloneReplicationPort");
+        
+        //setup replication agreement
+        String masterAgreementName = "masterAgreement1-" + machinename + "-" + instanceId;
+        cs.putString("internaldb.replication.master", masterAgreementName);
+        String cloneAgreementName = "cloneAgreement1-" + machinename + "-" + instanceId;
+        cs.putString("internaldb.replication.consumer", cloneAgreementName);
+
+        cs.commit(false);
+
+        // get connection to master
+        LDAPConnection masterConn = null;
+        ILdapConnFactory masterFactory = null;
+        try {
+            IConfigStore masterCfg = cs.getSubStore("preop.internaldb.master");
+            masterFactory = CMS.getLdapBoundConnFactory();
+            masterFactory.init(masterCfg);
+            masterConn = masterFactory.getConn();
+        } catch (Exception e) {
+            CMS.debug("setupEeplication: Failed to set up connection to master:" + e.toString());
+            e.printStackTrace();
+            releaseConnection(masterConn);
+            throw new IOException("Failed to set up replication: No connection to master");
+        }
+
+        // get connection to replica
+        LDAPConnection replicaConn = null;
+        ILdapConnFactory replicaFactory = null;
+        try {
+            IConfigStore replicaCfg = cs.getSubStore("internaldb");
+            replicaFactory = CMS.getLdapBoundConnFactory();
+            replicaFactory.init(replicaCfg);
+            replicaConn = replicaFactory.getConn();
+        } catch (Exception e) {
+            CMS.debug("SetupReplication: Failed to set up connection to replica:" + e.toString());
+            e.printStackTrace();
+            releaseConnection(masterConn);
+            releaseConnection(replicaConn);
+            throw new IOException("Failed to set up replication: No connection to replica");
+        }
+
+        try {
+            String master_hostname = cs.getString("preop.internaldb.master.ldapconn.host", "");
+            String master_replicationpwd = cs.getString("preop.internaldb.master.replication.password", "");
+            String replica_hostname = cs.getString("internaldb.ldapconn.host", "");
+            String replica_replicationpwd = cs.getString("preop.internaldb.replicationpwd", "");
+            String basedn = cs.getString("internaldb.basedn");            
+            String suffix = cs.getString("internaldb.basedn", "");
+            
+            String replicadn = "cn=replica,cn=\"" + suffix + "\",cn=mapping tree,cn=config";
+            CMS.debug("DatabasePanel setupReplication: replicadn=" + replicadn);
+
+            String masterBindUser = "Replication Manager " + masterAgreementName;
+            String cloneBindUser = "Replication Manager " + cloneAgreementName;
+
+            createReplicationManager(masterConn, masterBindUser, master_replicationpwd);
+            createReplicationManager(replicaConn, cloneBindUser, replica_replicationpwd);
+
+            String dir1 = getInstanceDir(masterConn);
+            createChangeLog(masterConn, dir1 + "/changelogs");
+
+            String dir2 = getInstanceDir(replicaConn);
+            createChangeLog(replicaConn, dir2 + "/changelogs");
+
+            int replicaId = cs.getInteger("dbs.beginReplicaNumber", 1);
+
+            replicaId = enableReplication(replicadn, masterConn, masterBindUser, basedn, replicaId);
+            replicaId = enableReplication(replicadn, replicaConn, cloneBindUser, basedn, replicaId);
+            cs.putString("dbs.beginReplicaNumber", Integer.toString(replicaId));
+
+            CMS.debug("setupReplication: Finished enabling replication");
+
+            createReplicationAgreement(replicadn, masterConn, masterAgreementName,
+                    replica_hostname, cloneReplicationPort, replica_replicationpwd, basedn,
+                    cloneBindUser, secure, replicationSecurity);
+
+            createReplicationAgreement(replicadn, replicaConn, cloneAgreementName,
+                    master_hostname, masterReplicationPort, master_replicationpwd, basedn,
+                    masterBindUser, secure, replicationSecurity);
+
+            // initialize consumer
+            initializeConsumer(replicadn, masterConn, masterAgreementName);
+
+            while (!replicationDone(replicadn, masterConn, masterAgreementName)) {
+                CMS.debug("setupReplication: Waiting for replication to complete");
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+
+            String status = replicationStatus(replicadn, masterConn, masterAgreementName);
+            if (!status.startsWith("0 ")) {
+                CMS.debug("setupReplication: consumer initialization failed. " +status);
+                throw new IOException("consumer initialization failed. " + status);
+            }
+
+            // remove master ldap password from password.conf (if present)
+            String passwordFile = cs.getString("passwordFile");
+            IConfigStore psStore = CMS.createFileConfigStore(passwordFile);
+            psStore.remove("master_internaldb");
+            psStore.commit(false);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            CMS.debug("setupReplication: " + e.toString());
+            throw new IOException("Failed to setup the replication for cloning.");
+        } finally {
+            releaseConnection(masterConn);
+            releaseConnection(replicaConn);
+        }
+}
+    
+    public static void createReplicationManager(LDAPConnection conn, String bindUser, String pwd)
+            throws LDAPException {
+        LDAPAttributeSet attrs = null;
+        LDAPEntry entry = null;
+        String dn = "cn=" + bindUser + ",ou=csusers,cn=config";
+        try {
+            attrs = new LDAPAttributeSet();
+            attrs.add(new LDAPAttribute("objectclass", "top"));
+            attrs.add(new LDAPAttribute("objectclass", "person"));
+            attrs.add(new LDAPAttribute("userpassword", pwd));
+            attrs.add(new LDAPAttribute("cn", bindUser));
+            attrs.add(new LDAPAttribute("sn", "manager"));
+            entry = new LDAPEntry(dn, attrs);
+            conn.add(entry);
+        } catch (LDAPException e) {
+            if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+                CMS.debug("createReplicationManager: Replication Manager has already used");
+                try {
+                    conn.delete(dn);
+                    conn.add(entry);
+                } catch (LDAPException ee) {
+                    CMS.debug("createReplicationManager: " + ee.toString());
+                }
+                return;
+            } else {
+                CMS.debug("createReplicationManager: Failed to create replication manager. Exception: "
+                        + e.toString());
+                throw e;
+            }
+        }
+
+        CMS.debug("createReplicationManager: Successfully created Replication Manager");
+    }
+
+    public static void createChangeLog(LDAPConnection conn, String dir)
+            throws LDAPException {
+        LDAPAttributeSet attrs = null;
+        LDAPEntry entry = null;
+        String dn = "cn=changelog5,cn=config";
+        try {
+            attrs = new LDAPAttributeSet();
+            attrs.add(new LDAPAttribute("objectclass", "top"));
+            attrs.add(new LDAPAttribute("objectclass", "extensibleObject"));
+            attrs.add(new LDAPAttribute("cn", "changelog5"));
+            attrs.add(new LDAPAttribute("nsslapd-changelogdir", dir));
+            entry = new LDAPEntry(dn, attrs);
+            conn.add(entry);
+        } catch (LDAPException e) {
+            if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+                CMS.debug("createChangeLog: Changelog entry has already used");
+                /* leave it, dont delete it because it will have operation error */
+                return;
+            } else {
+                CMS.debug("createChangeLog: Failed to create changelog entry. Exception: " + e.toString());
+                throw e;
+            }
+        }
+
+        CMS.debug("createChangeLog: Successfully create change log entry");
+    }
+
+    public static int enableReplication(String replicadn, LDAPConnection conn, String bindUser, String basedn, int id)
+            throws LDAPException {
+        CMS.debug("enableReplication: replicadn: " + replicadn);
+        LDAPAttributeSet attrs = null;
+        LDAPEntry entry = null;
+        try {
+            attrs = new LDAPAttributeSet();
+            attrs.add(new LDAPAttribute("objectclass", "top"));
+            attrs.add(new LDAPAttribute("objectclass", "nsDS5Replica"));
+            attrs.add(new LDAPAttribute("objectclass", "extensibleobject"));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaType", "3"));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN",
+                    "cn=" + bindUser + ",ou=csusers,cn=config"));
+            attrs.add(new LDAPAttribute("cn", "replica"));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaId", Integer.toString(id)));
+            attrs.add(new LDAPAttribute("nsds5flags", "1"));
+            entry = new LDAPEntry(replicadn, attrs);
+            conn.add(entry);
+        } catch (LDAPException e) {
+            if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+                /* BZ 470918 -we cant just add the new dn.  We need to do a replace instead 
+                 * until the DS code is fixed */
+                CMS.debug("enableReplication: " + replicadn + " has already been used");
+
+                try {
+                    entry = conn.read(replicadn);
+                    LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN");
+                    attr.addValue("cn=" + bindUser + ",ou=csusers,cn=config");
+                    LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr);
+                    conn.modify(replicadn, mod);
+                } catch (LDAPException ee) {
+                    CMS.debug("enableReplication: Failed to modify "
+                            + replicadn + " entry. Exception: " + e.toString());
+                }
+                return id;
+            } else {
+                CMS.debug("enableReplication: Failed to create "
+                        + replicadn + " entry. Exception: " + e.toString());
+                return id;
+            }
+        }
+
+        CMS.debug("enableReplication: Successfully create " + replicadn + " entry.");
+        return id + 1;
+    }
+
+    public static void createReplicationAgreement(String replicadn, LDAPConnection conn, String name, 
+            String replicahost, int replicaport, String replicapwd, String basedn, String bindUser, 
+            String secure, String replicationSecurity) throws LDAPException {
+        String dn = "cn=" + name + "," + replicadn;
+        CMS.debug("createReplicationAgreement: dn: " + dn);
+        LDAPEntry entry = null;
+        LDAPAttributeSet attrs = null;
+        try {
+            attrs = new LDAPAttributeSet();
+            attrs.add(new LDAPAttribute("objectclass", "top"));
+            attrs.add(new LDAPAttribute("objectclass",
+                    "nsds5replicationagreement"));
+            attrs.add(new LDAPAttribute("cn", name));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaHost", replicahost));
+
+            attrs.add(new LDAPAttribute("nsDS5ReplicaPort", "" + replicaport));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN",
+                    "cn=" + bindUser + ",ou=csusers,cn=config"));
+            attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple"));
+            attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd));
+
+            if (replicationSecurity.equals("SSL")) {
+                attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "SSL"));
+            } else if (replicationSecurity.equals("TLS")) {
+                attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "TLS"));
+            }
+
+            CMS.debug("About to set description attr to " + name);
+            attrs.add(new LDAPAttribute("description", name));
+
+            entry = new LDAPEntry(dn, attrs);
+            conn.add(entry);
+        } catch (LDAPException e) {
+            if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+                CMS.debug("createReplicationAgreement: " + dn + " has already used");
+                try {
+                    conn.delete(dn);
+                } catch (LDAPException ee) {
+                    CMS.debug("createReplicationAgreement: " + ee.toString());
+                    throw ee;
+                }
+
+                try {
+                    conn.add(entry);
+                } catch (LDAPException ee) {
+                    CMS.debug("createReplicationAgreement: " + ee.toString());
+                    throw ee;
+                }
+            } else {
+                CMS.debug("createReplicationAgreement: Failed to create "
+                        + dn + " entry. Exception: " + e.toString());
+                throw e;
+            }
+        }
+
+        CMS.debug("createReplicationAgreement: Successfully create replication agreement " + name);
+    }
+
+    public static void initializeConsumer(String replicadn, LDAPConnection conn, String name) throws LDAPException {
+        String dn = "cn=" + name + "," + replicadn;
+        CMS.debug("initializeConsumer: initializeConsumer dn: " + dn);
+        CMS.debug("initializeConsumer: initializeConsumer host: " + conn.getHost() + " port: " + conn.getPort());
+
+        LDAPAttribute attr = new LDAPAttribute("nsds5beginreplicarefresh", "start");
+        LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr);
+        conn.modify(dn, mod);
+
+        CMS.debug("initializeConsumer: Successfully initialized consumer");
+    }
+
+    public static boolean replicationDone(String replicadn, LDAPConnection conn, String name)
+            throws LDAPException, IOException {
+        String dn = "cn=" + name + "," + replicadn;
+        String filter = "(objectclass=*)";
+        String[] attrs = { "nsds5beginreplicarefresh" };
+
+        CMS.debug("replicationDone: dn: " + dn);
+
+        LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, attrs, true);
+        int count = results.getCount();
+        if (count < 1) {
+            throw new IOException("Replication entry not found");
+        }
+
+        LDAPEntry entry = results.next();
+        LDAPAttribute refresh = entry.getAttribute("nsds5beginreplicarefresh");
+        if (refresh == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public static String replicationStatus(String replicadn, LDAPConnection conn, String name)
+            throws IOException, LDAPException {
+        String dn = "cn=" + name + "," + replicadn;
+        String filter = "(objectclass=*)";
+        String[] attrs = { "nsds5replicalastinitstatus" };
+
+        CMS.debug("replicationStatus: dn: " + dn);
+
+        LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, attrs, false);
+
+        int count = results.getCount();
+        if (count < 1) {
+            throw new IOException("Replication entry not found");
+        }
+
+        LDAPEntry entry = results.next();
+        LDAPAttribute attr = entry.getAttribute("nsds5replicalastinitstatus");
+        if (attr != null) {
+            @SuppressWarnings("unchecked")
+            Enumeration<String> valsInAttr = attr.getStringValues();
+            if (valsInAttr.hasMoreElements()) {
+                return valsInAttr.nextElement();
+            } else {
+                throw new IOException("No value returned for nsds5replicalastinitstatus");
+            }
+        } else {
+            throw new IOException("nsDS5ReplicaLastInitStatus is null.");
+        }
+    }
+    
+    public static void reInitSubsystem(String csType) throws EBaseException {
+        CMS.reinit(IDBSubsystem.SUB_ID);
+        if (csType.equals("CA"))
+            CMS.reinit(ICertificateAuthority.ID);
+        CMS.reinit(IAuthSubsystem.ID);
+        CMS.reinit(IAuthzSubsystem.ID);
+        CMS.reinit(IUGSubsystem.ID);
+    }
+    
+    public static void createECCKeyPair(String token, String curveName, IConfigStore config, String ct)
+            throws NoSuchAlgorithmException, NoSuchTokenException, TokenException,
+            CryptoManager.NotInitializedException, EPropertyNotFound, EBaseException {
+        CMS.debug("createECCKeyPair: Generating ECC key pair with curvename=" + curveName + ", token=" + token);
+        KeyPair pair = null;
+        /*
+         * default ssl server cert to ECDHE unless stated otherwise
+         * note: IE only supports "ECDHE", but "ECDH" is more efficient
+         *
+         * for "ECDHE", server.xml should have the following for ciphers:
+         * +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+         * -TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+         *
+         * for "ECDH", server.xml should have the following for ciphers:
+         * -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+         * +TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+         */
+        String sslType = "ECDHE";
+        try {
+            sslType = config.getString(PCERT_PREFIX + ct + "ec.type", "ECDHE");
+        } catch (Exception e) {}
+
+        // ECDHE needs "SIGN" but no "DERIVE"
+        org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = {
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
+        };
+
+        // ECDH needs "DERIVE" but no any kind of "SIGN"
+        org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage ECDH_usages_mask[] = {
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER,
+        };
+
+        do {
+            if (ct.equals("sslserver") && sslType.equalsIgnoreCase("ECDH")) {
+                CMS.debug("SizePanel: createECCKeypair: sslserver cert for ECDH. Make sure server.xml is set " + 
+                          "properly with -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+                pair = CryptoUtil.generateECCKeyPair(token, curveName, null, ECDH_usages_mask);
+            } else {
+                if (ct.equals("sslserver")) {
+                    CMS.debug("SizePanel: createECCKeypair: sslserver cert for ECDHE. Make sure server.xml is set " +
+                              "properly with +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+                }
+                pair = CryptoUtil.generateECCKeyPair(token, curveName, null, usages_mask);
+            }
+
+            // XXX - store curve , w
+            byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
+            String kid = CryptoUtil.byte2string(id);
+            config.putString(PCERT_PREFIX + ct + ".privkey.id", kid);
+
+            // try to locate the private key
+            org.mozilla.jss.crypto.PrivateKey privk = CryptoUtil.findPrivateKeyFromID(CryptoUtil.string2byte(kid));
+            if (privk == null) {
+                CMS.debug("Found bad ECC key id " + kid);
+                pair = null;
+            }
+        } while (pair == null);
+
+        CMS.debug("Public key class " + pair.getPublic().getClass().getName());
+        byte encoded[] = pair.getPublic().getEncoded();
+        config.putString(PCERT_PREFIX + ct + ".pubkey.encoded", CryptoUtil.byte2string(encoded));
+
+        String keyAlgo = config.getString(PCERT_PREFIX + ct + ".signingalgorithm");
+        setSigningAlgorithm(ct, keyAlgo, config);
+    }
+
+    public static void createRSAKeyPair(String token, int keysize, IConfigStore config, String ct)
+            throws NoSuchAlgorithmException, NoSuchTokenException, TokenException,
+            CryptoManager.NotInitializedException, EPropertyNotFound, EBaseException {
+        /* generate key pair */
+        KeyPair pair = null;
+        do {
+            pair = CryptoUtil.generateRSAKeyPair(token, keysize);
+            byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
+            String kid = CryptoUtil.byte2string(id);
+            config.putString(PCERT_PREFIX + ct + ".privkey.id", kid);
+            // try to locate the private key
+            org.mozilla.jss.crypto.PrivateKey privk =
+                    CryptoUtil.findPrivateKeyFromID(CryptoUtil.string2byte(kid));
+            if (privk == null) {
+                CMS.debug("Found bad RSA key id " + kid);
+                pair = null;
+            }
+        } while (pair == null);
+
+        byte modulus[] = ((RSAPublicKey) pair.getPublic()).getModulus().toByteArray();
+        byte exponent[] = ((RSAPublicKey) pair.getPublic()).getPublicExponent().toByteArray();
+
+        config.putString(PCERT_PREFIX + ct + ".pubkey.modulus",
+                CryptoUtil.byte2string(modulus));
+        config.putString(PCERT_PREFIX + ct + ".pubkey.exponent",
+                CryptoUtil.byte2string(exponent));
+
+        String keyAlgo = config.getString(PCERT_PREFIX + ct + ".signingalgorithm");
+        setSigningAlgorithm(ct, keyAlgo, config);
+    }
+
+    public static void setSigningAlgorithm(String ct, String keyAlgo, IConfigStore config) throws EPropertyNotFound, EBaseException {
+        String systemType = config.getString("cs.type");         
+        if (systemType.equalsIgnoreCase("CA")) {
+            if (ct.equals("signing")) {
+                config.putString("ca.signing.defaultSigningAlgorithm", keyAlgo);
+                config.putString("ca.crl.MasterCRL.signingAlgorithm", keyAlgo);
+            } else if (ct.equals("ocsp_signing")) {
+                config.putString("ca.ocsp_signing.defaultSigningAlgorithm", keyAlgo);
+            }
+        } else if (systemType.equalsIgnoreCase("OCSP")) {
+            if (ct.equals("signing")) {
+                config.putString("ocsp.signing.defaultSigningAlgorithm", keyAlgo);
+            }
+        } else if (systemType.equalsIgnoreCase("KRA") || systemType.equalsIgnoreCase("DRM")) {
+            if (ct.equals("transport")) {
+                config.putString("kra.transportUnit.signingAlgorithm", keyAlgo);
+            }
+        }
+    }
+    
+    public static void configCert(HttpServletRequest request, HttpServletResponse response,
+            Context context, Cert certObj, WizardPanelBase panel) throws IOException {
+
+        IConfigStore config = CMS.getConfigStore();
+        String caType = certObj.getType();
+        CMS.debug("configCert: caType is " + caType);
+        X509CertImpl cert = null;
+        String certTag = certObj.getCertTag();
+
+        try {
+            updateConfig(config, certTag);
+            if (caType.equals("remote")) {
+                String v = config.getString("preop.ca.type", "");
+
+                CMS.debug("configCert: remote CA");
+                String pkcs10 = CertUtil.getPKCS10(config, PCERT_PREFIX, certObj, context);
+                certObj.setRequest(pkcs10);
+                String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem");
+                config.putString(subsystem + "." + certTag + ".certreq", pkcs10);
+                String profileId = config.getString(PCERT_PREFIX + certTag + ".profile");
+                String session_id = CMS.getConfigSDSessionId();
+                String sd_hostname = "";
+                int sd_ee_port = -1;
+                try {
+                    sd_hostname = config.getString("securitydomain.host", "");
+                    sd_ee_port = config.getInteger("securitydomain.httpseeport", -1);
+                } catch (Exception ee) {
+                    CMS.debug("configCert(): exception caught:" + ee.toString());
+                }
+                String sysType = config.getString("cs.type", "");
+                String machineName = config.getString("machineName", "");
+                String securePort = config.getString("service.securePort", "");
+                if (certTag.equals("subsystem")) {
+                    String content =
+                            "requestor_name="
+                                    + sysType + "-" + machineName + "-" + securePort + "&profileId=" + profileId
+                                    + "&cert_request_type=pkcs10&cert_request=" + URLEncoder.encode(pkcs10, "UTF-8")
+                                    + "&xmlOutput=true&sessionID=" + session_id;
+                    cert = CertUtil.createRemoteCert(sd_hostname, sd_ee_port,
+                            content, response, panel);
+                    if (cert == null) {
+                        throw new IOException("Error: remote certificate is null");
+                    }
+                } else if (v.equals("sdca")) {
+                    String ca_hostname = "";
+                    int ca_port = -1;
+                    try {
+                        ca_hostname = config.getString("preop.ca.hostname", "");
+                        ca_port = config.getInteger("preop.ca.httpsport", -1);
+                    } catch (Exception ee) {
+                    }
+
+                    String content =
+                            "requestor_name="
+                                    + sysType + "-" + machineName + "-" + securePort + "&profileId=" + profileId
+                                    + "&cert_request_type=pkcs10&cert_request=" + URLEncoder.encode(pkcs10, "UTF-8")
+                                    + "&xmlOutput=true&sessionID=" + session_id;
+                    cert = CertUtil.createRemoteCert(ca_hostname, ca_port,
+                            content, response, panel);
+                    if (cert == null) {
+                        throw new IOException("Error: remote certificate is null");
+                    }
+                } else if (v.equals("otherca")) {
+                    config.putString(subsystem + "." + certTag + ".cert",
+                            "...paste certificate here...");
+                } else {
+                    CMS.debug("NamePanel: no preop.ca.type is provided");
+                }
+            } else { // not remote CA, ie, self-signed or local
+                ISubsystem ca = CMS.getSubsystem(ICertificateAuthority.ID);
+
+                if (ca == null) {
+                    String s = PCERT_PREFIX + certTag + ".type";
+
+                    CMS.debug(
+                            "The value for " + s
+                                    + " should be remote, nothing else.");
+                    throw new IOException(
+                            "The value for " + s + " should be remote");
+                }
+
+                String pubKeyType = config.getString(
+                        PCERT_PREFIX + certTag + ".keytype");
+                if (pubKeyType.equals("rsa")) {
+
+                    String pubKeyModulus = config.getString(
+                            PCERT_PREFIX + certTag + ".pubkey.modulus");
+                    String pubKeyPublicExponent = config.getString(
+                            PCERT_PREFIX + certTag + ".pubkey.exponent");
+                    String subsystem = config.getString(
+                            PCERT_PREFIX + certTag + ".subsystem");
+
+                    if (certTag.equals("signing")) {
+                        X509Key x509key = CryptoUtil.getPublicX509Key(
+                                CryptoUtil.string2byte(pubKeyModulus),
+                                CryptoUtil.string2byte(pubKeyPublicExponent));
+
+                        cert = CertUtil.createLocalCert(config, x509key,
+                                PCERT_PREFIX, certTag, caType, context);
+                    } else {
+                        String cacert = config.getString("ca.signing.cert", "");
+
+                        if (cacert.equals("") || cacert.startsWith("...")) {
+                            certObj.setCert(
+                                    "...certificate be generated internally...");
+                            config.putString(subsystem + "." + certTag + ".cert",
+                                    "...certificate be generated internally...");
+                        } else {
+                            X509Key x509key = CryptoUtil.getPublicX509Key(
+                                    CryptoUtil.string2byte(pubKeyModulus),
+                                    CryptoUtil.string2byte(pubKeyPublicExponent));
+
+                            cert = CertUtil.createLocalCert(config, x509key,
+                                    PCERT_PREFIX, certTag, caType, context);
+                        }
+                    }
+                } else if (pubKeyType.equals("ecc")) {
+                    String pubKeyEncoded = config.getString(
+                            PCERT_PREFIX + certTag + ".pubkey.encoded");
+                    String subsystem = config.getString(
+                            PCERT_PREFIX + certTag + ".subsystem");
+
+                    if (certTag.equals("signing")) {
+
+                        X509Key x509key = CryptoUtil.getPublicX509ECCKey(CryptoUtil.string2byte(pubKeyEncoded));
+                        cert = CertUtil.createLocalCert(config, x509key,
+                                PCERT_PREFIX, certTag, caType, context);
+                    } else {
+                        String cacert = config.getString("ca.signing.cert", "");
+
+                        if (cacert.equals("") || cacert.startsWith("...")) {
+                            certObj.setCert(
+                                    "...certificate be generated internally...");
+                            config.putString(subsystem + "." + certTag + ".cert",
+                                    "...certificate be generated internally...");
+                        } else {
+                            X509Key x509key = CryptoUtil.getPublicX509ECCKey(
+                                    CryptoUtil.string2byte(pubKeyEncoded));
+
+                            cert = CertUtil.createLocalCert(config, x509key,
+                                    PCERT_PREFIX, certTag, caType, context);
+                        }
+                    }
+                } else {
+                    // invalid key type
+                    CMS.debug("Invalid key type " + pubKeyType);
+                }
+                if (cert != null) {
+                    if (certTag.equals("subsystem"))
+                        CertUtil.addUserCertificate(cert);
+                }
+            } // done self-signed or local
+
+            if (cert != null) {
+                byte[] certb = cert.getEncoded();
+                String certs = CryptoUtil.base64Encode(certb);
+
+                certObj.setCert(certs);
+                String subsystem = config.getString(
+                        PCERT_PREFIX + certTag + ".subsystem");
+                config.putString(subsystem + "." + certTag + ".cert", certs);
+            }
+            config.commit(false);
+        } catch (IOException e) {
+            throw e;
+        } catch (Exception e) {
+            CMS.debug("configCert() exception caught:" + e.toString());
+        }
+    }
+    
+    public static void updateConfig(IConfigStore config, String certTag)
+            throws EBaseException, IOException {
+        String token = config.getString("preop.module.token");
+        String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem");
+        String nickname = getNickname(config, certTag);
+
+        CMS.debug("NamePanel: updateConfig() for certTag " + certTag);
+        if (certTag.equals("signing") || certTag.equals("ocsp_signing")) {
+            CMS.debug("NamePanel: setting signing nickname=" + nickname);
+            config.putString(subsystem + "." + certTag + ".cacertnickname", nickname);
+            config.putString(subsystem + "." + certTag + ".certnickname", nickname);
+        }
+
+        // if KRA, hardware token needs param "kra.storageUnit.hardware" in CS.cfg
+        String cstype = config.getString("cs.type", null);
+        cstype = cstype.toLowerCase();
+        if (cstype.equals("kra")) {
+            if (!token.equals("Internal Key Storage Token")) {
+                if (certTag.equals("storage")) {
+                    config.putString(subsystem + ".storageUnit.hardware", token);
+                    config.putString(subsystem + ".storageUnit.nickName", token + ":" + nickname);
+                } else if (certTag.equals("transport")) {
+                    config.putString(subsystem + ".transportUnit.nickName", token + ":" + nickname);
+                }
+            } else { // software token
+                if (certTag.equals("storage")) {
+                    config.putString(subsystem + ".storageUnit.nickName", nickname);
+                } else if (certTag.equals("transport")) {
+                    config.putString(subsystem + ".transportUnit.nickName", nickname);
+                }
+            }
+        }
+
+        String serverCertNickname = nickname;
+        String path = CMS.getConfigStore().getString("instanceRoot", "");
+        if (certTag.equals("sslserver")) {
+            if (!token.equals("Internal Key Storage Token")) {
+                serverCertNickname = token + ":" + nickname;
+            }
+            PrintStream ps = new PrintStream(new FileOutputStream(path + "/conf/serverCertNick.conf"));
+            ps.println(serverCertNickname);
+            ps.close();
+        }
+
+        config.putString(subsystem + "." + certTag + ".nickname", nickname);
+        config.putString(subsystem + "." + certTag + ".tokenname", token);
+        if (certTag.equals("audit_signing")) {
+            if (!token.equals("Internal Key Storage Token") && !token.equals("")) {
+                config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+                        token + ":" + nickname);
+            } else {
+                config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+                        nickname);
+            }
+        }
+         
+        // for system certs verification
+        if (!token.equals("Internal Key Storage Token") && !token.equals("")) {
+            config.putString(subsystem + ".cert." + certTag + ".nickname",
+                    token + ":" + nickname);
+        } else {
+            config.putString(subsystem + ".cert." + certTag + ".nickname", nickname);
+        }
+
+        config.commit(false);
+        CMS.debug("updateConfig() done");
+    }
+    
+    public static String getNickname(IConfigStore config, String certTag) throws EBaseException {
+        String instanceID = config.getString("instanceId", "");
+         
+        String nickname = certTag + "Cert cert-" + instanceID;
+        String preferredNickname = null;
+        try {
+            preferredNickname = config.getString(PCERT_PREFIX + certTag + ".nickname", null);
+        } catch (EBaseException e) {
+        }
+         
+        if (preferredNickname != null) {
+            return preferredNickname;
+        }
+        return nickname;
+    }
+
+    public static int getPortFromSecurityDomain(String domainXML, String host, int port, String csType,
+            String givenTag, String wantedTag) throws SAXException, IOException, ParserConfigurationException {
+        IConfigStore cs = CMS.getConfigStore();
+        ByteArrayInputStream bis = new ByteArrayInputStream(domainXML.getBytes());
+        XMLObject parser = new XMLObject(bis);
+        Document doc = parser.getDocument();
+        NodeList nodeList = doc.getElementsByTagName(csType);
+
+        // save domain name in cfg
+        cs.putString("securitydomain.name", parser.getValue("Name"));
+
+        int len = nodeList.getLength();
+        CMS.debug("len: "+ len);
+        for (int i = 0; i < len; i++) {
+            Node node = nodeList.item(i);
+            String v_host = parser.getValuesFromContainer(node, "Host").elementAt(0);
+            CMS.debug("v_host " + v_host);
+            String v_given_port = parser.getValuesFromContainer(node, givenTag).elementAt(0);
+            CMS.debug("v_port " + v_given_port);
+            if (!(v_host.equals(host) && v_given_port.equals(port + "")))
+                continue;
+            String wanted_port = parser.getValuesFromContainer(node, wantedTag).elementAt(0);
+            return Integer.parseInt(wanted_port);
+        }
+
+        return 0;
+    }
+    
+    public static void updateCloneConfig()
+            throws EBaseException, IOException {
+        IConfigStore config = CMS.getConfigStore();
+        String cstype = config.getString("cs.type", null);
+        cstype = cstype.toLowerCase();
+        if (cstype.equals("kra")) {
+            String token = config.getString("preop.module.token");
+            if (!token.equals("Internal Key Storage Token")) {
+                CMS.debug("NamePanel: updating configuration for KRA clone with hardware token");
+                String subsystem = config.getString(PCERT_PREFIX + "storage.subsystem");
+                String storageNickname = getNickname(config, "storage");
+                String transportNickname = getNickname(config, "transport");
+
+                config.putString(subsystem + ".storageUnit.hardware", token);
+                config.putString(subsystem + ".storageUnit.nickName", token + ":" + storageNickname);
+                config.putString(subsystem + ".transportUnit.nickName", token + ":" + transportNickname);
+                config.commit(false);
+            } else { // software token
+                // parameters already set
+            }
+        }
+
+        // audit signing cert
+        String audit_nn = config.getString(cstype + ".audit_signing" + ".nickname", "");
+        String audit_tk = config.getString(cstype + ".audit_signing" + ".tokenname", "");
+        if (!audit_tk.equals("Internal Key Storage Token") && !audit_tk.equals("")) {
+            config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+                    audit_tk + ":" + audit_nn);
+        } else {
+            config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+                    audit_nn);
+        }
+    }
+    
+    public static void handleCertRequest(IConfigStore config, String certTag, Cert cert) throws EPropertyNotFound,
+            EBaseException, InvalidKeyException, NotInitializedException, TokenException, NoSuchAlgorithmException,
+            NoSuchProviderException, CertificateException, SignatureException, IOException {
+
+        // get public key
+        String pubKeyType = config.getString(PCERT_PREFIX + certTag + ".keytype");
+        String algorithm = config.getString(PCERT_PREFIX + certTag + ".keyalgorithm");
+        X509Key pubk = null;
+        if (pubKeyType.equals("rsa")) {
+            pubk = getRSAX509Key(config, certTag);
+        } else if (pubKeyType.equals("ecc")) {
+            pubk = getECCX509Key(config, certTag);
+        } else {
+            CMS.debug("handleCertRequest() - " + "pubKeyType " + pubKeyType + " is unsupported!");
+            return;
+        }
+
+        CMS.debug("handleCertRequest: tag=" + certTag);
+        if (pubk == null) {
+            CMS.debug("handleCertRequest: error getting public key null");
+            return;
+        }
+
+        // get private key
+        String privKeyID = config.getString(PCERT_PREFIX + certTag + ".privkey.id");
+        CMS.debug("privKeyID=" + privKeyID);
+        byte[] keyIDb = CryptoUtil.string2byte(privKeyID);
+
+        PrivateKey privk = CryptoUtil.findPrivateKeyFromID(keyIDb);
+        if (privk == null) {
+            CMS.debug("handleCertRequest: error getting private key");
+        }
+
+        // construct cert request
+        String caDN = config.getString(PCERT_PREFIX + certTag + ".dn");
+
+        cert.setDN(caDN);
+        PKCS10 certReq = CryptoUtil.createCertificationRequest(caDN, pubk, privk, algorithm);
+
+        CMS.debug("handleCertRequest: created cert request");
+        byte[] certReqb = certReq.toByteArray();
+        String certReqs = CryptoUtil.base64Encode(certReqb);
+        String certReqf = CryptoUtil.reqFormat(certReqs);
+
+        String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem");
+        config.putString(subsystem + "." + certTag + ".certreq", certReqs);
+        config.commit(false);
+        cert.setRequest(certReqf);
+
+    }
+    
+    public static X509Key getECCX509Key(IConfigStore config, String certTag) throws EPropertyNotFound, EBaseException,
+            InvalidKeyException {
+        X509Key pubk = null;
+        String pubKeyEncoded = config.getString(PCERT_PREFIX + certTag + ".pubkey.encoded");
+        pubk = CryptoUtil.getPublicX509ECCKey(CryptoUtil.string2byte(pubKeyEncoded));
+        return pubk;
+    }
+
+    public static X509Key getRSAX509Key(IConfigStore config, String certTag) throws EPropertyNotFound, EBaseException,
+            InvalidKeyException {
+        X509Key pubk = null;
+
+        String pubKeyModulus = config.getString(PCERT_PREFIX + certTag + ".pubkey.modulus");
+        String pubKeyPublicExponent = config.getString(PCERT_PREFIX + certTag + ".pubkey.exponent");
+        pubk = CryptoUtil.getPublicX509Key(
+                CryptoUtil.string2byte(pubKeyModulus),
+                CryptoUtil.string2byte(pubKeyPublicExponent));
+        return pubk;
+    }
+
+    public static int handleCerts(Cert cert) throws IOException, EBaseException, CertificateException,
+            NotInitializedException, TokenException, InvalidKeyException {
+        String certTag = cert.getCertTag();
+        String subsystem = cert.getSubsystem();
+        String nickname = cert.getNickname();
+        IConfigStore config = CMS.getConfigStore();
+
+        boolean enable = config.getBoolean(PCERT_PREFIX + certTag + ".enable", true);
+        if (!enable) return 0;
+
+        CMS.debug("handleCerts(): for cert tag " + cert.getCertTag());
+        String b64 = cert.getCert();
+        String tokenname = config.getString("preop.module.token", "");
+
+        if (cert.getType().equals("local") && b64.equals("...certificate be generated internally...")) {
+            String pubKeyType = config.getString(PCERT_PREFIX + certTag + ".keytype");
+            X509Key x509key = null;
+            if (pubKeyType.equals("rsa")) {
+                x509key = getRSAX509Key(config, certTag);
+            } else if (pubKeyType.equals("ecc")) {
+                x509key = getECCX509Key(config, certTag);
+            }
+
+            if (findCertificate(tokenname, nickname)) {
+                if (!certTag.equals("sslserver")) return 0;
+            }
+            X509CertImpl impl = CertUtil.createLocalCert(config, x509key,
+                    PCERT_PREFIX, certTag, cert.getType(), null);
+
+            if (impl != null) {
+                byte[] certb = impl.getEncoded();
+                String certs = CryptoUtil.base64Encode(certb);
+
+                cert.setCert(certs);
+                config.putString(subsystem + "." + certTag + ".cert", certs);
+                CMS.debug("handleCerts(): nickname=" + nickname);
+
+                try {
+                    if (certTag.equals("sslserver") && findBootstrapServerCert())
+                        deleteBootstrapServerCert();
+                    if (findCertificate(tokenname, nickname))
+                        deleteCert(tokenname, nickname);
+                    if (certTag.equals("signing") && subsystem.equals("ca"))
+                        CryptoUtil.importUserCertificate(impl, nickname);
+                    else
+                        CryptoUtil.importUserCertificate(impl, nickname, false);
+                    CMS.debug("handleCerts(): cert imported for certTag " + certTag);
+                } catch (Exception ee) {
+                    CMS.debug("handleCerts(): import certificate for certTag=" + certTag + " Exception: " + ee.toString());
+                }
+            }
+        } else if (cert.getType().equals("remote")) {
+            if (b64 != null && b64.length() > 0 && !b64.startsWith("...")) {
+                CMS.debug("handleCert(): process remote...import cert");
+                String b64chain = cert.getCertChain();
+               
+                try {
+                    if (certTag.equals("sslserver") && findBootstrapServerCert())
+                        deleteBootstrapServerCert();
+                    if (findCertificate(tokenname, nickname)) {
+                        deleteCert(tokenname, nickname);
+                    }
+                } catch (Exception e) {
+                    CMS.debug("CertRequestPanel update (remote): deleteCert Exception=" + e.toString());
+                }
+                byte[] certb = CryptoUtil.base64Decode(b64);
+
+                config.putString(subsystem + "." + certTag + ".cert", b64);
+                try {
+                    CryptoManager cm = CryptoManager.getInstance();
+                    X509Certificate x509cert = cm.importCertPackage(certb, nickname);
+                    CryptoUtil.trustCertByNickname(nickname);
+                    
+                    X509Certificate[] certchains = cm.buildCertificateChain(x509cert);
+                    X509Certificate leaf = null;
+
+                    if (certchains != null) {
+                        CMS.debug("handleCerts(): certchains length=" + certchains.length);
+                        leaf = certchains[certchains.length - 1];
+                    }
+
+                    if (leaf == null) {
+                        CMS.debug("handleCerts(): leaf is null!");
+                        throw new IOException("leaf is null");
+                    }
+
+                    if (b64chain != null && b64chain.length() != 0) {
+                        CMS.debug("handlecerts: cert might not have contained chain...calling importCertificateChain: "
+                                + b64chain);
+                        try {
+                            CryptoUtil.importCertificateChain(CryptoUtil.normalizeCertAndReq(b64chain));
+                        } catch (Exception e) {
+                            CMS.debug("handleCerts(): importCertChain: Exception: " + e.toString());
+                        }
+                    }
+
+                    InternalCertificate icert = (InternalCertificate) leaf;
+
+                    icert.setSSLTrust(
+                            InternalCertificate.TRUSTED_CA
+                                    | InternalCertificate.TRUSTED_CLIENT_CA
+                                    | InternalCertificate.VALID_CA);
+                    CMS.debug("handleCerts(): import certificate successfully, certTag=" + certTag);
+                } catch (Exception ee) {
+                    CMS.debug("handleCerts: import certificate for certTag=" + certTag + " Exception: "+ ee.toString());
+                }
+
+            } else {
+                CMS.debug("handleCert(): b64 not set");
+                return 1;
+            }
+        } else {
+            b64 = CryptoUtil.stripCertBrackets(b64.trim());
+            String certs = CryptoUtil.normalizeCertStr(b64);
+            byte[] certb = CryptoUtil.base64Decode(certs);
+            X509CertImpl impl = new X509CertImpl(certb);
+            try {
+                if (certTag.equals("sslserver") && findBootstrapServerCert())
+                    deleteBootstrapServerCert();
+                if (findCertificate(tokenname, nickname)) {
+                    deleteCert(tokenname, nickname);
+                }
+            } catch (Exception ee) {
+                CMS.debug("handleCert(): deleteCert Exception=" + ee.toString());
+            }
+
+            try {
+                if (certTag.equals("signing") && subsystem.equals("ca"))
+                    CryptoUtil.importUserCertificate(impl, nickname);
+                else
+                    CryptoUtil.importUserCertificate(impl, nickname, false);
+            } catch (Exception ee) {
+                CMS.debug("handleCerts(): Failed to import user certificate." + ee.toString());
+                return 1;
+            }
+        }
+
+        //update requests in request queue for local certs to allow renewal
+        if ((cert.getType().equals("local")) || (cert.getType().equals("selfsign"))) {
+            CertUtil.updateLocalRequest(config, certTag, cert.getRequest(), "pkcs10", null);
+        }
+
+        if (certTag.equals("signing") && subsystem.equals("ca")) {
+            String NickName = nickname;
+            if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token"))
+                NickName = tokenname + ":" + nickname;
+
+            CMS.debug("handleCerts(): set trust on CA signing cert " + NickName);
+            CryptoUtil.trustCertByNickname(NickName);
+            CMS.reinit(ICertificateAuthority.ID);
+        }
+        return 0;
+    }
+    
+    public static void setCertPermissions(String tag) throws EBaseException, NotInitializedException,
+            ObjectNotFoundException, TokenException {
+        if (tag.equals("signing")) return;
+
+        IConfigStore cs = CMS.getConfigStore();
+        String nickname = cs.getString("preop.cert." + tag + ".nickname", "");
+        String tokenname = cs.getString("preop.module.token", "");
+        if (!tokenname.equals("Internal Key Storage Token"))
+            nickname = tokenname + ":" + nickname;
+
+        CryptoManager cm = CryptoManager.getInstance();
+        X509Certificate c = cm.findCertByNickname(nickname);
+
+        if (c instanceof InternalCertificate) {
+            InternalCertificate ic = (InternalCertificate) c;
+            ic.setSSLTrust(InternalCertificate.USER);
+            ic.setEmailTrust(InternalCertificate.USER);
+            if (tag.equals("audit_signing")) {
+                ic.setObjectSigningTrust(InternalCertificate.USER
+                        | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER);
+            } else {
+                ic.setObjectSigningTrust(InternalCertificate.USER);
+            }
+        }
+    }
+    
+    public static boolean findCertificate(String tokenname, String nickname) throws NotInitializedException,
+            TokenException, IOException {
+        IConfigStore cs = CMS.getConfigStore();
+        CryptoManager cm = CryptoManager.getInstance();
+
+        String fullnickname = nickname;
+        boolean hardware = false;
+        if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")) {
+            hardware = true;
+            fullnickname = tokenname + ":" + nickname;
+        }
+
+        X509Certificate cert = null;
+        try {
+            cert = cm.findCertByNickname(fullnickname);
+        } catch (ObjectNotFoundException e) {
+            return false;
+        }
+
+        if (cert == null)
+            return false;
+        try {
+            @SuppressWarnings("unused")
+            boolean done = cs.getBoolean("preop.CertRequestPanel.done"); // check for errors
+        } catch (Exception ee) {
+            if (hardware) {
+                CMS.debug("CertRequestPanel findCertificate: The certificate with the same nickname: "
+                        + fullnickname + " has been found on HSM. Please remove it before proceeding.");
+                throw new IOException("The certificate with the same nickname: "
+                        + fullnickname + " has been found on HSM. Please remove it before proceeding.");
+            }
+        }
+        return true;
+    }
+
+
+    public static boolean findBootstrapServerCert() throws EBaseException, NotInitializedException, TokenException {
+        IConfigStore cs = CMS.getConfigStore();
+
+        String instanceID = cs.getString("instanceId", "");
+        String nickname = "Server-Cert cert-" + instanceID;
+
+        CryptoManager cm = CryptoManager.getInstance();
+        X509Certificate cert;
+        try {
+            cert = cm.findCertByNickname(nickname);
+        } catch (ObjectNotFoundException e) {
+            return false;
+        }
+        Principal issuerDN = cert.getIssuerDN();
+        Principal subjectDN = cert.getSubjectDN();
+        if (issuerDN.equals(subjectDN)) return true;
+
+        return false;
+    }
+
+    public static void deleteBootstrapServerCert() throws EBaseException, NotInitializedException,
+            NoSuchTokenException, TokenException {
+        IConfigStore cs = CMS.getConfigStore();
+        String instanceID = cs.getString("instanceId", "");
+        String nickname = "Server-Cert cert-" + instanceID;
+        deleteCert("Internal Key Storage Token", nickname);
+    }
+    
+    public static void deleteCert(String tokenname, String nickname) throws NotInitializedException,
+            NoSuchTokenException, TokenException {
+
+        CryptoManager cm = CryptoManager.getInstance();
+        CryptoToken tok = cm.getTokenByName(tokenname);
+        CryptoStore store = tok.getCryptoStore();
+        String fullnickname = nickname;
+        if (!tokenname.equals("") &&
+                !tokenname.equals("Internal Key Storage Token") &&
+                !tokenname.equals("internal"))
+            fullnickname = tokenname + ":" + nickname;
+
+        CMS.debug("deleteCert: nickname=" + fullnickname);
+        X509Certificate cert;
+        try {
+            cert = cm.findCertByNickname(fullnickname);
+        } catch (ObjectNotFoundException e) {
+            CMS.debug("deleteCert: cert not found");
+            return;
+        }
+
+        if (store instanceof PK11Store) {
+            PK11Store pk11store = (PK11Store) store;
+            try {
+                pk11store.deleteCertOnly(cert);
+            } catch (NoSuchItemOnTokenException e) {
+            }
+            CMS.debug("deleteCert: cert deleted successfully");
+        }
+    }
+    
+    public static void backupKeys(String pwd, String fname) throws EPropertyNotFound, EBaseException,
+            NotInitializedException, ObjectNotFoundException, TokenException, DigestException,
+            InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidBERException,
+            CertificateEncodingException, IllegalStateException, IllegalBlockSizeException, BadPaddingException,
+            IOException {
+        CMS.debug("backupKeys(): start");
+        IConfigStore cs = CMS.getConfigStore();
+        String certlist = cs.getString("preop.cert.list");
+
+        StringTokenizer st = new StringTokenizer(certlist, ",");
+        CryptoManager cm = CryptoManager.getInstance();
+
+        Password pass = new org.mozilla.jss.util.Password(pwd.toCharArray());
+        SEQUENCE encSafeContents = new SEQUENCE();
+        SEQUENCE safeContents = new SEQUENCE();
+        while (st.hasMoreTokens()) {
+            String t = st.nextToken();
+            if (t.equals("sslserver"))
+                continue;
+            String nickname = cs.getString("preop.cert." + t + ".nickname");
+            String modname = cs.getString("preop.module.token");
+
+            if (!modname.equals("Internal Key Storage Token"))
+                nickname = modname + ":" + nickname;
+
+            X509Certificate x509cert = cm.findCertByNickname(nickname);
+            byte localKeyId[] = addCertBag(x509cert, nickname, safeContents);
+            PrivateKey pkey = cm.findPrivKeyByCert(x509cert);
+            addKeyBag(pkey, x509cert, pass, localKeyId, encSafeContents);
+        }
+
+        X509Certificate[] cacerts = cm.getCACerts();
+
+        for (int i = 0; i < cacerts.length; i++) {
+            String nickname = null;
+            addCertBag(cacerts[i], nickname, safeContents);
+        }
+
+        AuthenticatedSafes authSafes = new AuthenticatedSafes();
+        authSafes.addSafeContents(safeContents);
+        authSafes.addSafeContents(encSafeContents);
+        PFX pfx = new PFX(authSafes);
+        pfx.computeMacData(pass, null, 5);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        pfx.encode(bos);
+        byte[] output = bos.toByteArray();
+        cs.putString("preop.pkcs12", CryptoUtil.byte2string(output));
+        pass.clear();
+        cs.commit(false);
+
+        if (fname != null) {
+            FileOutputStream fout = null;
+            try {
+                fout = new FileOutputStream(fname);
+                fout.write(output);
+            } catch (Exception e) {
+                throw new IOException("Failed to store keys in backup file" + e);
+            } finally {
+                if (fout != null) {
+                    fout.close();
+                }
+            }
+        }
+    }
+
+    public static void addKeyBag(PrivateKey pkey, X509Certificate x509cert,
+            Password pass, byte[] localKeyId, SEQUENCE safeContents)
+            throws NoSuchAlgorithmException, InvalidBERException, InvalidKeyException,
+            InvalidAlgorithmParameterException, NotInitializedException, TokenException, IllegalStateException,
+            IllegalBlockSizeException, BadPaddingException, CharConversionException {
+
+        PasswordConverter passConverter = new PasswordConverter();
+
+        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+        byte salt[] = random.generateSeed(4); // 4 bytes salt
+        byte[] priData = getEncodedKey(pkey);
+
+        PrivateKeyInfo pki = (PrivateKeyInfo)
+                ASN1Util.decode(PrivateKeyInfo.getTemplate(), priData);
+        ASN1Value key = EncryptedPrivateKeyInfo.createPBE(
+                PBEAlgorithm.PBE_SHA1_DES3_CBC,
+                pass, salt, 1, passConverter, pki);
+        SET keyAttrs = createBagAttrs(
+                x509cert.getSubjectDN().toString(), localKeyId);
+        SafeBag keyBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG,
+                key, keyAttrs);
+        safeContents.addElement(keyBag);
+
+    }
+
+    public static byte[] addCertBag(X509Certificate x509cert, String nickname,
+            SEQUENCE safeContents) throws CertificateEncodingException, NoSuchAlgorithmException, CharConversionException {
+        byte[] localKeyId = null;
+
+        ASN1Value cert = new OCTET_STRING(x509cert.getEncoded());
+        localKeyId = createLocalKeyId(x509cert);
+        SET certAttrs = null;
+        if (nickname != null)
+            certAttrs = createBagAttrs(nickname, localKeyId);
+        SafeBag certBag = new SafeBag(SafeBag.CERT_BAG,
+                new CertBag(CertBag.X509_CERT_TYPE, cert), certAttrs);
+        safeContents.addElement(certBag);
+
+        return localKeyId;
+    }
+
+    public static byte[] getEncodedKey(PrivateKey pkey) throws NotInitializedException, NoSuchAlgorithmException,
+            TokenException, IllegalStateException, CharConversionException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
+        CryptoManager cm = CryptoManager.getInstance();
+        CryptoToken token = cm.getInternalKeyStorageToken();
+        KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3);
+        SymmetricKey sk = kg.generate();
+        KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+        byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+        IVParameterSpec param = new IVParameterSpec(iv);
+        wrapper.initWrap(sk, param);
+        byte[] enckey = wrapper.wrap(pkey);
+        Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+        c.initDecrypt(sk, param);
+        byte[] recovered = c.doFinal(enckey);
+        return recovered;
+    }
+
+    public static byte[] createLocalKeyId(X509Certificate cert)
+            throws NoSuchAlgorithmException, CertificateEncodingException {
+
+        // SHA1 hash of the X509Cert der encoding
+        byte certDer[] = cert.getEncoded();
+
+        MessageDigest md = MessageDigest.getInstance("SHA");
+
+        md.update(certDer);
+        return md.digest();
+
+    }
+
+    public static SET createBagAttrs(String nickName, byte localKeyId[]) throws CharConversionException {
+
+        SET attrs = new SET();
+        SEQUENCE nickNameAttr = new SEQUENCE();
+
+        nickNameAttr.addElement(SafeBag.FRIENDLY_NAME);
+        SET nickNameSet = new SET();
+
+        nickNameSet.addElement(new BMPString(nickName));
+        nickNameAttr.addElement(nickNameSet);
+        attrs.addElement(nickNameAttr);
+        SEQUENCE localKeyAttr = new SEQUENCE();
+
+        localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
+        SET localKeySet = new SET();
+
+        localKeySet.addElement(new OCTET_STRING(localKeyId));
+        localKeyAttr.addElement(localKeySet);
+        attrs.addElement(localKeyAttr);
+        return attrs;
+
+    }
+    
+    public static void createAdminCertificate(String certRequest, String certRequestType, String subject)
+            throws InvalidBERException, IOException, InvalidKeyException, InvalidKeyFormatException,
+            NoSuchAlgorithmException, SignatureException, NoSuchProviderException, EBaseException {
+        IConfigStore cs = CMS.getConfigStore();
+        X509Key x509key = null;
+        if (certRequestType.equals("crmf")) {
+            byte[] b = CMS.AtoB(certRequest);
+            SEQUENCE crmfMsgs = CryptoUtil.parseCRMFMsgs(b);
+            subject = CryptoUtil.getSubjectName(crmfMsgs);
+            x509key = CryptoUtil.getX509KeyFromCRMFMsgs(crmfMsgs);
+        } else if (certRequestType.equals("pkcs10")) {
+            byte[] b = CMS.AtoB(certRequest);
+            PKCS10 pkcs10 = new PKCS10(b);
+            x509key = pkcs10.getSubjectPublicKeyInfo();
+        }
+
+        if (x509key == null) {
+            CMS.debug("createAdminCertificate() - x509key is null!");
+            throw new IOException("x509key is null");
+        }
+
+        cs.putString(PCERT_PREFIX + "admin.dn", subject);
+        String caType = cs.getString(PCERT_PREFIX + "admin.type", "local");
+        X509CertImpl impl = CertUtil.createLocalCert(cs, x509key, PCERT_PREFIX, "admin", caType, null);
+
+        // update the locally created request for renewal
+        CertUtil.updateLocalRequest(cs, "admin", certRequest, certRequestType, subject);
+
+        ISubsystem ca = CMS.getSubsystem("ca");
+        if (ca != null) {
+            createPKCS7(impl);
+        }
+        cs.putString("preop.admincert.serialno.0", impl.getSerialNumber().toString(16));
+    }
+    
+    public static void createPKCS7(X509CertImpl cert) throws IOException {
+        IConfigStore cs = CMS.getConfigStore();
+        ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca");
+        CertificateChain cachain = ca.getCACertChain();
+        java.security.cert.X509Certificate[] cacerts = cachain.getChain();
+        X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+        int m = 1, n = 0;
+
+        for (; n < cacerts.length; m++, n++) {
+            userChain[m] = (X509CertImpl) cacerts[n];
+        }
+
+        userChain[0] = cert;
+        PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+                new ContentInfo(new byte[0]), userChain, new SignerInfo[0]);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        p7.encodeSignedData(bos);
+        byte[] p7Bytes = bos.toByteArray();
+        String p7Str = CMS.BtoA(p7Bytes);
+        cs.putString("preop.admincert.pkcs7", CryptoUtil.normalizeCertStr(p7Str));
+    }
+    
+    public static void createAdmin(String uid, String email, String name, String pwd) throws IOException,
+            EBaseException {
+        IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+        IConfigStore config = CMS.getConfigStore();
+        String groupName = config.getString("preop.admin.group", "Certificate Manager Agents");
+
+        IUser user = null;
+
+        try {
+            user = system.createUser(uid);
+            user.setEmail(email);
+            user.setPassword(pwd);
+            user.setFullName(name);
+            user.setUserType("adminType");
+            user.setState("1");
+            user.setPhone("");
+            system.addUser(user);
+        } catch (LDAPException e) {
+            CMS.debug("AdminPanel createAdmin: addUser " + e.toString());
+            if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
+                throw new IOException(e.toString());
+            }
+        } catch (Exception e) {
+            CMS.debug("AdminPanel createAdmin: addUser " + e.toString());
+            throw new IOException(e.toString());
+        }
+
+        IGroup group = null;
+
+        group = system.getGroupFromName(groupName);
+        if (!group.isMember(uid)) {
+            group.addMemberName(uid);
+            system.modifyGroup(group);
+        }
+        group = system.getGroupFromName("Administrators");
+        if (!group.isMember(uid)) {
+            group.addMemberName(uid);
+            system.modifyGroup(group);
+        }
+
+        String select = config.getString("securitydomain.select", "");
+        if (select.equals("new")) {
+            group = system.getGroupFromName("Security Domain Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+
+            group = system.getGroupFromName("Enterprise CA Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+
+            group = system.getGroupFromName("Enterprise KRA Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+
+            group = system.getGroupFromName("Enterprise RA Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+
+            group = system.getGroupFromName("Enterprise TKS Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+
+            group = system.getGroupFromName("Enterprise OCSP Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+
+            group = system.getGroupFromName("Enterprise TPS Administrators");
+            if (!group.isMember(uid)) {
+                group.addMemberName(uid);
+                system.modifyGroup(group);
+            }
+        }
+    }
+    
+    public static String submitAdminCertRequest(String ca_hostname, int ca_port, String profileId,
+            String certRequestType, String certRequest, String subjectDN) throws IOException, EBaseException,
+            SAXException, ParserConfigurationException {
+        IConfigStore config = CMS.getConfigStore();
+
+        if (profileId == null) {
+            profileId = config.getString("preop.admincert.profile", "caAdminCert");
+        }
+        certRequest = URLEncoder.encode(certRequest, "UTF-8");
+        String session_id = CMS.getConfigSDSessionId();
+        String content = "profileId=" + profileId + "&cert_request_type=" + certRequestType +
+                "&cert_request=" + certRequest + "&xmlOutput=true&sessionID=" + session_id + "&subject=" + subjectDN;
+
+        String c = getHttpResponse(ca_hostname, ca_port, true, "/ca/ee/ca/profileSubmit", content, null, null);
+
+        // retrieve the request Id and admin certificate
+        if (c != null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = new XMLObject(bis);
+
+            String status = parser.getValue("Status");
+            CMS.debug("submitAdminXertRequest: status=" + status);
+            if (status.equals(AUTH_FAILURE)) {
+                throw new EAuthException(AUTH_FAILURE);
+            } else if (!status.equals(SUCCESS)) {
+                String error = parser.getValue("Error");
+                throw new IOException(error);
+            }
+
+            IConfigStore cs = CMS.getConfigStore();
+            String id = parser.getValue("Id");
+
+            cs.putString("preop.admincert.requestId.0", id);
+            String serial = parser.getValue("serialno");
+
+            cs.putString("preop.admincert.serialno.0", serial);
+            String b64 = parser.getValue("b64");
+            
+            // save in a file for access by ImportAdminCertPanel
+            String instanceRoot = cs.getString("instanceRoot", "");
+            String dir = instanceRoot + File.separator + "conf" + File.separator + "admin.b64";
+            cs.putString("preop.admincert.b64", dir);
+            
+            PrintStream ps = new PrintStream(new FileOutputStream(dir));
+            ps.println(b64);
+            ps.flush();
+            ps.close();
+            
+            return b64;
+        } else {
+            throw new IOException("submitAdminCertRequest: Failed to get response from ca");
+        }
+    }
+    
+    public static void createSecurityDomain() throws EBaseException, LDAPException, NumberFormatException, IOException,
+            SAXException, ParserConfigurationException {
+        IConfigStore cs = CMS.getConfigStore();
+        IConfigStore dbCfg = cs.getSubStore("internaldb");
+        ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory();
+        dbFactory.init(dbCfg);
+        LDAPConnection conn = dbFactory.getConn();
+        LDAPEntry entry = null;
+        LDAPAttributeSet attrs = null;
+
+        // Create security domain ldap entry
+        String basedn = cs.getString("internaldb.basedn");
+        String secdomain = cs.getString("securitydomain.name");
+
+        String dn = "ou=Security Domain," + basedn;
+        attrs = new LDAPAttributeSet();
+        attrs.add(new LDAPAttribute("objectclass", "top"));
+        attrs.add(new LDAPAttribute("objectclass", "pkiSecurityDomain"));
+        attrs.add(new LDAPAttribute("name", secdomain));
+        attrs.add(new LDAPAttribute("ou", "Security Domain"));
+        entry = new LDAPEntry(dn, attrs);
+        conn.add(entry);
+
+        // create list containers
+        String clist[] = { "CAList", "OCSPList", "KRAList", "RAList", "TKSList", "TPSList" };
+        for (int i = 0; i < clist.length; i++) {
+            dn = "cn=" + clist[i] + ",ou=Security Domain," + basedn;
+            attrs = new LDAPAttributeSet();
+            attrs.add(new LDAPAttribute("objectclass", "top"));
+            attrs.add(new LDAPAttribute("objectclass", "pkiSecurityGroup"));
+            attrs.add(new LDAPAttribute("cn", clist[i]));
+            entry = new LDAPEntry(dn, attrs);
+            conn.add(entry);
+        }
+
+        // Add this host
+        String cn = CMS.getEESSLHost() + ":" + CMS.getAdminPort();
+        dn = "cn=" + cn + ",cn=CAList,ou=Security Domain," + basedn;
+        String subsystemName = cs.getString("preop.subsystem.name");
+        attrs = new LDAPAttributeSet();
+        attrs.add(new LDAPAttribute("objectclass", "top"));
+        attrs.add(new LDAPAttribute("objectclass", "pkiSubsystem"));
+        attrs.add(new LDAPAttribute("Host", CMS.getEESSLHost()));
+        attrs.add(new LDAPAttribute("SecurePort", CMS.getEESSLPort()));
+        attrs.add(new LDAPAttribute("SecureAgentPort", CMS.getAgentPort()));
+        attrs.add(new LDAPAttribute("SecureAdminPort", CMS.getAdminPort()));
+        if (CMS.getEEClientAuthSSLPort() != null) {
+            attrs.add(new LDAPAttribute("SecureEEClientAuthPort", CMS.getEEClientAuthSSLPort()));
+        }
+        attrs.add(new LDAPAttribute("UnSecurePort", CMS.getEENonSSLPort()));
+        attrs.add(new LDAPAttribute("Clone", "FALSE"));
+        attrs.add(new LDAPAttribute("SubsystemName", subsystemName));
+        attrs.add(new LDAPAttribute("cn", cn));
+        attrs.add(new LDAPAttribute("DomainManager", "TRUE"));
+        entry = new LDAPEntry(dn, attrs);
+        conn.add(entry);
+
+        CMS.debug("createSecurityDomain(): finish updating domain info");
+        conn.disconnect();
+
+        // Fetch the "new" security domain and display it
+        // CMS.debug("createSecurityDomain(): Dump contents of new Security Domain . . .");
+        // @SuppressWarnings("unused")
+        // String c = getDomainXML(CMS.getEESSLHost(), Integer.parseInt(CMS.getAdminPort()), true);
+    }
+    
+    public static void updateSecurityDomain() throws IOException, SAXException, ParserConfigurationException,
+            EPropertyNotFound, EBaseException {
+        IConfigStore cs = CMS.getConfigStore();
+
+        int sd_agent_port = cs.getInteger("securitydomain.httpsagentport");
+        int sd_admin_port = cs.getInteger("securitydomain.httpsadminport");
+        String select = cs.getString("preop.subsystem.select");
+        String type = cs.getString("cs.type");
+        String sd_host = cs.getString("securitydomain.host");
+        String subsystemName = cs.getString("preop.subsystem.name");
+
+        boolean cloneMaster = false;
+
+        if (select.equals("clone") && type.equalsIgnoreCase("CA") && isSDHostDomainMaster(cs)) {
+            cloneMaster = true;
+            CMS.debug("Cloning a domain master");
+        }
+
+        String cloneStr = select.equals("clone") ? "&clone=true" : "&clone=false";
+        String domainMasterStr = cloneMaster ? "&dm=true" : "&dm=false";
+        String eecaStr = (CMS.getEEClientAuthSSLPort() != null) ? "&eeclientauthsport=" + CMS.getEEClientAuthSSLPort()
+                : "";
+
+        updateDomainXML(sd_host, sd_agent_port, true,
+                "/ca/agent/ca/updateDomainXML",
+                "list=" + type + "List"
+                + "&type=" + type
+                + "&host=" + CMS.getEESSLHost()
+                + "&name=" + subsystemName
+                + "&sport=" + CMS.getEESSLPort()
+                + domainMasterStr
+                + cloneStr
+                + "&agentsport=" + CMS.getAgentPort()
+                + "&adminsport=" + CMS.getAdminPort()
+                + eecaStr
+                + "&httpport=" + CMS.getEENonSSLPort());
+
+        // Fetch the "updated" security domain and display it
+        CMS.debug("updateSecurityDomain(): Dump contents of updated Security Domain . . .");
+        @SuppressWarnings("unused")
+        String c = getDomainXML(sd_host, sd_admin_port, true);
+    }
+    
+    public static boolean isSDHostDomainMaster(IConfigStore config) throws EPropertyNotFound, EBaseException,
+            IOException, SAXException, ParserConfigurationException {
+        String dm = "false";
+
+        String hostname = config.getString("securitydomain.host");
+        int httpsadminport = config.getInteger("securitydomain.httpsadminport");
+
+        CMS.debug("isSDHostDomainMaster(): Getting domain.xml from CA...");
+        String c = getDomainXML(hostname, httpsadminport, true);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+        XMLObject parser = new XMLObject(bis);
+        Document doc = parser.getDocument();
+        NodeList nodeList = doc.getElementsByTagName("CA");
+
+        int len = nodeList.getLength();
+        for (int i = 0; i < len; i++) {
+            Vector<String> v_hostname = parser.getValuesFromContainer(nodeList.item(i), "Host");
+            Vector<String> v_https_admin_port = parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort");
+            Vector<String> v_domain_mgr = parser.getValuesFromContainer(nodeList.item(i), "DomainManager");
+
+            if (v_hostname.elementAt(0).equals(hostname) &&
+                    v_https_admin_port.elementAt(0).equals(Integer.toString(httpsadminport))) {
+                dm = v_domain_mgr.elementAt(0).toString();
+                break;
+            }
+        }
+        return dm.equalsIgnoreCase("true");
+    }
+    
+    public static void updateDomainXML(String hostname, int port, boolean https,
+            String servlet, String uri) throws IOException, EBaseException, SAXException, ParserConfigurationException {
+        CMS.debug("WizardPanelBase updateDomainXML start hostname=" + hostname + " port=" + port);
+        IConfigStore cs = CMS.getConfigStore();
+        String nickname = cs.getString("preop.cert.subsystem.nickname", "");
+        String tokenname = cs.getString("preop.module.token", "");
+
+        if (!tokenname.equals("") &&
+                !tokenname.equals("Internal Key Storage Token") &&
+                !tokenname.equals("internal")) {
+            nickname = tokenname + ":" + nickname;
+        }
+        CMS.debug("updateDomainXML() nickname=" + nickname);
+
+        String c = getHttpResponse(hostname, port, https, servlet, uri, nickname, null);
+        if (c != null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject obj = new XMLObject(bis);
+            String status = obj.getValue("Status");
+            CMS.debug("WizardPanelBase updateDomainXML: status=" + status);
+
+            if (status.equals(SUCCESS)) {
+                return;
+            } else {
+                String error = obj.getValue("Error");
+                throw new IOException(error);
+            }
+        }
+    }
+    
+    public static void updateConnectorInfo(String ownagenthost, String ownagentsport)
+            throws IOException, EBaseException, SAXException, ParserConfigurationException {
+        IConfigStore cs = CMS.getConfigStore();
+        int port = -1;
+        String url = "";
+        String host = null;
+        String transportCert = "";
+
+        url = cs.getString("preop.ca.url", "");
+        if (!url.equals("")) {
+            host = cs.getString("preop.ca.hostname", "");
+            port = cs.getInteger("preop.ca.httpsadminport", -1);
+            transportCert = cs.getString("kra.transport.cert", "");
+        }
+
+        if (host == null) {
+            CMS.debug("updateConnectorInfo(): preop.ca.url is not defined. External CA selected. No transport certificate setup is required");
+        } else {
+            CMS.debug("updateConnectorInfo(): Transport certificate is being setup in " + url);
+            String session_id = CMS.getConfigSDSessionId();
+            String content = "ca.connector.KRA.enable=true&ca.connector.KRA.local=false&ca.connector.KRA.timeout=30"
+                    + "&ca.connector.KRA.uri=/kra/agent/kra/connector&ca.connector.KRA.host=" + ownagenthost
+                    + "&ca.connector.KRA.port=" + ownagentsport
+                    + "&ca.connector.KRA.transportCert=" + URLEncoder.encode(transportCert, "UTF-8")
+                    + "&sessionID=" + session_id;
+
+            updateConnectorInfo(host, port, true, content);
+        }
+    }
+
+    public static void updateConnectorInfo(String host, int port, boolean https,
+            String content) throws IOException, SAXException, ParserConfigurationException {
+        CMS.debug("updateConnectorInfo start");
+        String c = getHttpResponse(host, port, https, "/ca/admin/ca/updateConnector", content, null, null);
+        if (c != null) {
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = null;
+            parser = new XMLObject(bis);
+            String status = parser.getValue("Status");
+            CMS.debug("updateConnectorInfo: status=" + status);
+            if (!status.equals(SUCCESS)) {
+                String error = parser.getValue("Error");
+                throw new IOException(error);
+            }
+        }
+    }
+    
+    public static void setupClientAuthUser() throws EBaseException, CertificateException, IOException, SAXException,
+            ParserConfigurationException, LDAPException {
+        IConfigStore cs = CMS.getConfigStore();
+        String host = cs.getString("preop.ca.hostname", "");
+        int port = cs.getInteger("preop.ca.httpsadminport", -1);
+
+        // retrieve CA subsystem certificate from the CA
+        IUGSubsystem system =
+                (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+        String id = "";
+
+        String b64 = getSubsystemCert(host, port, true);
+        if (b64 != null) {
+            int num = cs.getInteger("preop.subsystem.count", 0);
+            id = "CA-" + host + "-" + port;
+            num++;
+            cs.putInteger("preop.subsystem.count", num);
+            cs.putInteger("subsystem.count", num);
+            IUser user = system.createUser(id);
+            user.setFullName(id);
+            user.setEmail("");
+            user.setPassword("");
+            user.setUserType("agentType");
+            user.setState("1");
+            user.setPhone("");
+            X509CertImpl[] certs = new X509CertImpl[1];
+            certs[0] = new X509CertImpl(CMS.AtoB(b64));
+            user.setX509Certificates(certs);
+            try {
+                system.addUser(user);
+            } catch (LDAPException e) {
+                if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
+                    throw e;
+                }
+            }
+            CMS.debug("DonePanel display: successfully add the user");
+            system.addUserCert(user);
+            CMS.debug("DonePanel display: successfully add the user certificate");
+            cs.commit(false);
+        }
+
+        String groupName = "Trusted Managers";
+        IGroup group = system.getGroupFromName(groupName);
+        if (!group.isMember(id)) {
+            group.addMemberName(id);
+            system.modifyGroup(group);
+            CMS.debug("DonePanel display: successfully added the user to the group.");
+        }
+
+    }
+    
+    public static String getSubsystemCert(String host, int port, boolean https)
+            throws IOException, SAXException, ParserConfigurationException {
+        CMS.debug("getSubsystemCert() start");
+        String c = getHttpResponse(host, port, https, "/ca/admin/ca/getSubsystemCert", null, null, null);
+        if (c != null) {
+            ByteArrayInputStream bis =
+                    new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = new XMLObject(bis);
+            String status = parser.getValue("Status");
+            if (status.equals(SUCCESS)) {
+                String s = parser.getValue("Cert");
+                return s;
+            } else {
+                return null;
+            }
+        }
+        return null;
+    }
+    
+    public static void importCACertToOCSP() throws IOException, EBaseException, CertificateEncodingException {
+        IConfigStore config = CMS.getConfigStore();
+
+        // get certificate chain from CA
+        String b64 = config.getString("preop.ca.pkcs7", "");
+        if (b64.equals("")) {
+            throw new IOException("Failed to get certificate chain.");
+        }
+
+        // this could be a chain
+        java.security.cert.X509Certificate[] certs = com.netscape.cmsutil.util.Cert.mapCertFromPKCS7(b64);
+        java.security.cert.X509Certificate leafCert = null;
+        if (certs != null && certs.length > 0) {
+            if (certs[0].getSubjectDN().getName().equals(certs[0].getIssuerDN().getName())) {
+                leafCert = certs[certs.length - 1];
+            } else {
+                leafCert = certs[0];
+            }
+
+            IOCSPAuthority ocsp = (IOCSPAuthority) CMS.getSubsystem(IOCSPAuthority.ID);
+            IDefStore defStore = ocsp.getDefaultStore();
+
+            // (1) need to normalize (sort) the chain
+            // (2) store certificate (and certificate chain) into
+            // database
+            ICRLIssuingPointRecord rec = defStore.createCRLIssuingPointRecord(
+                    leafCert.getSubjectDN().getName(),
+                    BIG_ZERO,
+                    MINUS_ONE, null, null);
+
+            rec.set(ICRLIssuingPointRecord.ATTR_CA_CERT, leafCert.getEncoded());
+            defStore.addCRLIssuingPoint(leafCert.getSubjectDN().getName(), rec);
+
+            CMS.debug("importCACertToOCSP(): Added CA certificate.");
+        }
+    }
+    
+    public static void updateOCSPConfig()
+            throws IOException, EBaseException, SAXException, ParserConfigurationException {
+        IConfigStore config = CMS.getConfigStore();
+        String cahost = config.getString("preop.ca.hostname", "");
+        int caport = config.getInteger("preop.ca.httpsport", -1);
+        String ocsphost = CMS.getAgentHost();
+        int ocspport = Integer.parseInt(CMS.getAgentPort());
+        String session_id = CMS.getConfigSDSessionId();
+        String content = "xmlOutput=true&sessionID=" + session_id + "&ocsp_host=" + ocsphost + "&ocsp_port=" + ocspport;
+
+        String c = getHttpResponse(cahost, caport, true, "/ca/ee/ca/updateOCSPConfig", content, null, null);
+        if (c == null || c.equals("")) {
+            CMS.debug("WizardPanelBase updateOCSPConfig: content is null.");
+            throw new IOException("The server you want to contact is not available");
+        } else {
+            ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+            XMLObject parser = new XMLObject(bis);
+            
+            String status = parser.getValue("Status");
+            CMS.debug("WizardPanelBase updateOCSPConfig: status=" + status);
+
+            if (status.equals(SUCCESS)) {
+                CMS.debug("WizardPanelBase updateOCSPConfig: Successfully update the OCSP configuration in the CA.");
+            } else if (status.equals(AUTH_FAILURE)) {
+                throw new EAuthException(AUTH_FAILURE);
+            } else {
+                String error = parser.getValue("Error");
+                throw new IOException(error);
+            }
+        }
+    }
+    
+    public static void setupDBUser(String dbuser) throws CertificateException, LDAPException, EBaseException,
+            NotInitializedException, ObjectNotFoundException, TokenException, IOException {
+        IUGSubsystem system =
+                (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+
+        String b64 = getSubsystemCert();
+        if (b64 == null) {
+            CMS.debug("setupDBUser(): failed to fetch subsystem cert");
+            return;
+        }
+
+        IUser user = system.createUser(dbuser);
+        user.setFullName(dbuser);
+        user.setEmail("");
+        user.setPassword("");
+        user.setUserType("agentType");
+        user.setState("1");
+        user.setPhone("");
+        X509CertImpl[] certs = new X509CertImpl[1];
+        certs[0] = new X509CertImpl(CMS.AtoB(b64));
+        user.setX509Certificates(certs);
+        system.addUser(user);
+        CMS.debug("setupDBUser(): successfully added the user");
+        system.addUserCert(user);
+        CMS.debug("setupDBUser(): successfully add the user certificate");
+    }
+
+    public static String getSubsystemCert() throws EBaseException, NotInitializedException, ObjectNotFoundException,
+            TokenException, CertificateEncodingException, IOException {
+        IConfigStore cs = CMS.getConfigStore();
+        String nickname = cs.getString("preop.cert.subsystem.nickname", "");
+        String tokenname = cs.getString("preop.module.token", "");
+
+        if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")
+                && !tokenname.equals("")) {
+            nickname = tokenname + ":" + nickname;
+        }
+
+        CMS.debug("DonePanel getSubsystemCert: nickname=" + nickname);
+
+        CryptoManager cm = CryptoManager.getInstance();
+        org.mozilla.jss.crypto.X509Certificate cert = cm.findCertByNickname(nickname);
+        if (cert == null) {
+            CMS.debug("DonePanel getSubsystemCert: subsystem cert is null");
+            return null;
+        }
+        byte[] bytes = cert.getEncoded();
+        String s = CryptoUtil.normalizeCertStr(CryptoUtil.base64Encode(bytes));
+        return s;
+    }
+    
+    public static void updateNextRanges() throws EBaseException, LDAPException {
+        IConfigStore cs = CMS.getConfigStore();
+        
+        String endRequestNumStr = cs.getString("dbs.endRequestNumber", "");
+        String endSerialNumStr = cs.getString("dbs.endSerialNumber", "");
+        String type = cs.getString("cs.type");
+        String basedn = cs.getString("internaldb.basedn");
+        
+        BigInteger endRequestNum = new BigInteger(endRequestNumStr);
+        BigInteger endSerialNum = new BigInteger(endSerialNumStr);
+        BigInteger oneNum = new BigInteger("1");
+
+        // update global next range entries
+        IConfigStore dbCfg = cs.getSubStore("internaldb");
+        ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory();
+        dbFactory.init(dbCfg);
+        LDAPConnection conn = dbFactory.getConn();
+
+        String serialdn = "";
+        if (type.equals("CA")) {
+            serialdn = "ou=certificateRepository,ou=" + type.toLowerCase() + "," + basedn;
+        } else {
+            serialdn = "ou=keyRepository,ou=" + type.toLowerCase() + "," + basedn;
+        }
+        LDAPAttribute attrSerialNextRange =
+                new LDAPAttribute("nextRange", endSerialNum.add(oneNum).toString());
+        LDAPModification serialmod = new LDAPModification(LDAPModification.REPLACE, attrSerialNextRange);
+        conn.modify(serialdn, serialmod);
+
+        String requestdn = "ou=" + type.toLowerCase() + ",ou=requests," + basedn;
+        LDAPAttribute attrRequestNextRange =
+                new LDAPAttribute("nextRange", endRequestNum.add(oneNum).toString());
+        LDAPModification requestmod = new LDAPModification(LDAPModification.REPLACE, attrRequestNextRange);
+        conn.modify(requestdn, requestmod);
+
+        conn.disconnect();
+    }
+    
+    /**
+     * save variables needed for cloning and remove preops
+     * @throws EBaseException 
+     */
+    public static void removePreopConfigEntries() throws EBaseException {
+        IConfigStore cs = CMS.getConfigStore();
+        String type = cs.getString("cs.type");
+        String list = cs.getString("preop.cert.list", "");
+        StringTokenizer st = new StringTokenizer(list, ",");
+
+        while (st.hasMoreTokens()) {
+            String ss = st.nextToken();
+            if (ss.equals("sslserver"))
+                continue;
+            cs.putString("cloning." + ss + ".nickname", cs.getString("preop.cert." + ss + ".nickname", ""));
+            cs.putString("cloning." + ss + ".dn", cs.getString("preop.cert." + ss + ".dn", ""));
+            cs.putString("cloning." + ss + ".keytype", cs.getString("preop.cert." + ss + ".keytype", ""));
+            cs.putString("cloning." + ss + ".keyalgorithm", cs.getString("preop.cert." + ss + ".keyalgorithm", ""));
+            cs.putString("cloning." + ss + ".privkey.id", cs.getString("preop.cert." + ss + ".privkey.id", ""));
+            cs.putString("cloning." + ss + ".pubkey.exponent",
+                    cs.getString("preop.cert." + ss + ".pubkey.exponent", ""));
+            cs.putString("cloning." + ss + ".pubkey.modulus",
+                    cs.getString("preop.cert." + ss + ".pubkey.modulus", ""));
+            cs.putString("cloning." + ss + ".pubkey.encoded",
+                    cs.getString("preop.cert." + ss + ".pubkey.encoded", ""));
+        }
+        cs.putString("cloning.module.token", cs.getString("preop.module.token", ""));
+        cs.putString("cloning.list", list);
+
+        // more cloning variables needed for non-ca clones
+
+        if (!type.equals("CA")) {
+            String val = cs.getString("preop.ca.hostname", "");
+            if (val.length() > 0)
+                cs.putString("cloning.ca.hostname", val);
+
+            val = cs.getString("preop.ca.httpport", "");
+            if (val.length() != 0)
+                cs.putString("cloning.ca.httpport", val);
+
+            val = cs.getString("preop.ca.httpsport", "");
+            if (val.length() != 0)
+                cs.putString("cloning.ca.httpsport", val);
+
+            val = cs.getString("preop.ca.list", "");
+            if (val.length() != 0)
+                cs.putString("cloning.ca.list", val);
+
+            val = cs.getString("preop.ca.pkcs7", "");
+            if (val.length() != 0)
+                cs.putString("cloning.ca.pkcs7", val);
+
+            val = cs.getString("preop.ca.type", "");
+            if (val.length() != 0)
+                cs.putString("cloning.ca.type", val);
+        }
+
+        // save EC type for sslserver cert (if present)
+        cs.putString("jss.ssl.sslserver.ectype", cs.getString("preop.cert.sslserver.ec.type", "ECDHE"));
+
+        cs.removeSubStore("preop");
+        cs.commit(false);
+    }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff582561c847591d8a3b1e503e544d747046b2ed
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+package com.netscape.cms.servlet.csadmin;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import com.netscape.cms.servlet.csadmin.model.ConfigurationData;
+import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData;
+import com.netscape.cms.servlet.csadmin.model.DomainInfo;
+import com.netscape.cms.servlet.csadmin.model.InstallToken;
+import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest;
+
+/**
+ * @author alee
+ *
+ */
+@Path("/installer")
+public interface SystemConfigurationResource {
+    
+    @POST
+    @Path("configure")
+    @Produces({ MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED})
+    public ConfigurationResponseData configure(MultivaluedMap<String, String> form);
+    
+    @POST
+    @Path("configure")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public ConfigurationResponseData configure(ConfigurationData data);
+    
+    @POST
+    @Path("installToken")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public InstallToken getInstallToken(InstallTokenRequest data);
+    
+    @GET
+    @Path("domainInfo")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public DomainInfo getDomainInfo();
+    
+    
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java
new file mode 100644
index 0000000000000000000000000000000000000000..73b2f0ba436bdf23af6ef493bfe96ec7904ead8e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java
@@ -0,0 +1,944 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Random;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.util.IncorrectPasswordException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.base.CMSException;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.csadmin.model.CertData;
+import com.netscape.cms.servlet.csadmin.model.ConfigurationData;
+import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData;
+import com.netscape.cms.servlet.csadmin.model.DomainInfo;
+import com.netscape.cms.servlet.csadmin.model.InstallToken;
+import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * @author alee
+ *
+ */
+public class SystemConfigurationResourceService extends CMSResourceService implements SystemConfigurationResource {
+    IConfigStore cs;
+    String csType;
+    String csState;
+    boolean isMasterCA = false;
+    String instanceRoot;
+
+    public static String SUCCESS = "0";
+    public static final String RESTART_SERVER_AFTER_CONFIGURATION =
+            "restart_server_after_configuration";
+    private static Random mRandom = null;
+
+    public SystemConfigurationResourceService() throws EPropertyNotFound, EBaseException {
+        cs = CMS.getConfigStore();
+        csType = cs.getString("cs.type");
+        csState = cs.getString("cs.state");
+        String domainType = cs.getString("securitydomain.select", "existingdomain");
+        if (csType.equals("CA") && domainType.equals("new")) {
+            isMasterCA = true;
+        }
+        instanceRoot = cs.getString("instanceRoot");
+        mRandom = new Random();
+    }
+
+    /* (non-Javadoc)
+     * @see com.netscape.cms.servlet.csadmin.SystemConfigurationResource#configure(javax.ws.rs.core.MultivaluedMap)
+     */
+    @Override
+    public ConfigurationResponseData configure(MultivaluedMap<String, String> form) {
+        ConfigurationData data = new ConfigurationData(form);
+        return configure(data);
+    }
+
+    /* (non-Javadoc)
+     * @see com.netscape.cms.servlet.csadmin.SystemConfigurationResource#configure(com.netscape.cms.servlet.csadmin.data.ConfigurationData)
+     */
+    @Override
+    public ConfigurationResponseData configure(ConfigurationData data){
+        if (csState.equals("1")) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "System is already configured");
+        }
+
+        String certList;
+        try {
+            certList = cs.getString("preop.cert.list");
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CMSException("Unable to get certList from config file");
+        }
+
+        validateData(data);
+        ConfigurationResponseData response = new ConfigurationResponseData();
+
+        // specify module and log into token
+        String token = data.getToken();
+        if (token == null) {
+            token = ConfigurationData.TOKEN_DEFAULT;
+        }
+        cs.putString("preop.module.token", token);
+
+        if (! token.equals(ConfigurationData.TOKEN_DEFAULT)) {
+            try {
+                CryptoManager cryptoManager = CryptoManager.getInstance();
+                CryptoToken ctoken = cryptoManager.getTokenByName(token);
+                String tokenpwd = data.getTokenPassword();
+                ConfigurationUtils.loginToken(ctoken, tokenpwd);
+            } catch (NotInitializedException e) {
+                throw new CMSException("Token is not initialized");
+            } catch (NoSuchTokenException e) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Invalid Token provided. No such token.");
+            } catch (TokenException e) {
+                e.printStackTrace();
+                throw new CMSException("Token Exception" + e);
+            } catch (IncorrectPasswordException e) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Incorrect Password provided for token.");
+            }
+        }
+
+        //configure security domain
+        String securityDomainType = data.getSecurityDomainType();
+        String securityDomainName = data.getSecurityDomainName();
+        String securityDomainURL = data.getSecurityDomainUri();
+        String domainXML = null;
+        if (securityDomainType.equals(ConfigurationData.NEW_DOMAIN)) {
+            cs.putString("preop.securitydomain.select", "new");
+            cs.putString("securitydomain.select", "new");
+            cs.putString("preop.securitydomain.name", securityDomainName);
+            cs.putString("securitydomain.name", securityDomainName);
+            cs.putString("securitydomain.host", CMS.getEENonSSLHost());
+            cs.putString("securitydomain.httpport", CMS.getEENonSSLPort());
+            cs.putString("securitydomain.httpsagentport", CMS.getAgentPort());
+            cs.putString("securitydomain.httpseeport", CMS.getEESSLPort());
+            cs.putString("securitydomain.httpsadminport", CMS.getAdminPort());
+            cs.putString("preop.cert.subsystem.type", "local");
+            cs.putString("preop.cert.subsystem.profile", "subsystemCert.profile");
+        } else {
+            cs.putString("preop.securitydomain.select", "existing");
+            cs.putString("securitydomain.select", "existing");
+            cs.putString("preop.cert.subsystem.type", "remote");
+            cs.putString("preop.cert.subsystem.profile", "caInternalAuthSubsystemCert");
+
+            // contact and log onto security domain
+            URL secdomainURL;
+            String host;
+            int port;
+            try {
+                secdomainURL = new URL(securityDomainURL);
+                host = secdomainURL.getHost();
+                port = secdomainURL.getPort();
+                cs.putString("securitydomain.host", host);
+                cs.putInteger("securitydomain.httpsadminport",port);
+                ConfigurationUtils.importCertChain(host, port, "/ca/admin/ca/getCertChain", "securitydomain");
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Failed to import certificate chain from security domain master: " + e);
+            }
+
+            // log onto security domain and get token
+            String user = data.getSecurityDomainUser();
+            String pass = data.getSecurityDomainPassword();
+            String installToken;
+            try {
+                installToken = ConfigurationUtils.getInstallToken(host, port, user, pass);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Failed to obtain installation token from security domain: " + e);
+            }
+
+            if (installToken == null) {
+                throw new CMSException("Failed to obtain installation token from security domain");
+            }
+            CMS.setConfigSDSessionId(installToken);
+
+            try {
+                domainXML = ConfigurationUtils.getDomainXML(host, port, true);
+                ConfigurationUtils.getSecurityDomainPorts(domainXML, host, port);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Failed to obtain security domain decriptor from security domain master: " + e);
+            }
+        }
+
+        cs.putString("preop.subsystem.name", data.getSubsystemName());
+
+        // is this a clone of another subsystem?
+        if (data.getIsClone().equals("false")) {
+            cs.putString("preop.subsystem.select", "new");
+            cs.putString("subsystem.select", "New");
+        } else {
+            cs.putString("preop.subsystem.select", "clone");
+            cs.putString("subsystem.select", "Clone");
+
+            StringTokenizer t = new StringTokenizer(certList, ",");
+            while (t.hasMoreTokens()) {
+                String tag = t.nextToken();
+                if (tag.equals("sslserver")) {
+                    cs.putBoolean("preop.cert." + tag + ".enable", true);
+                } else {
+                    cs.putBoolean("preop.cert." + tag + ".enable", false);
+                }
+            }
+
+            String cloneUri = data.getCloneUri();
+            URL url = null;
+            try {
+                url = new URL(cloneUri);
+            } catch (MalformedURLException e) {
+                // should not reach here as this check is done in validate()
+            }
+            String masterHost = url.getHost();
+            int masterPort = url.getPort();
+
+            // check and store cloneURI information
+            boolean validCloneUri;
+            try {
+                validCloneUri = ConfigurationUtils.isValidCloneURI(domainXML, masterHost, masterPort);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Error in determining whether clone URI is valid");
+            }
+
+            if (!validCloneUri) {
+                throw new CMSException(Response.Status.BAD_REQUEST,
+                        "Invalid clone URI provided.  Does not match the available subsystems in the security domain");
+            }
+
+            if (csType.equals("CA")) {
+                try {
+                    ConfigurationUtils.importCertChain(masterHost, masterPort, "/ca/ee/ca/getCertChain", "clone");
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new CMSException("Failed to import certificate chain from master" + e);
+                }
+            }
+
+            try {
+                ConfigurationUtils.getConfigEntriesFromMaster();
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Failed to obtain configuration entries from the master for cloning " + e);
+            }
+
+            // restore certs from P12 file
+            if (token.equals(ConfigurationData.TOKEN_DEFAULT)) {
+                String p12File = data.getP12File();
+                String p12Pass = data.getP12Password();
+                try {
+                    ConfigurationUtils.restoreCertsFromP12(p12File, p12Pass);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new CMSException("Failed to restore certificates from p12 file" + e);
+                }
+            }
+
+            boolean cloneReady = ConfigurationUtils.isCertdbCloned();
+            if (!cloneReady) {
+                CMS.debug("clone does not have all the certificates.");
+                throw new CMSException("Clone does not have all the required certificates");
+            }
+        }
+
+        // Hierarchy Panel
+        if (csType.equals("CA") && data.getIsClone().equals("false")) {
+            if (data.getHierarchy().equals("root")) {
+                cs.putString("preop.hierarchy.select", "root");
+                cs.putString("hierarchy.select", "Root");
+                cs.putString("preop.ca.type", "sdca");
+            } else if (data.getHierarchy().equals("join")) {
+                cs.putString("preop.cert.signing.type", "remote");
+                cs.putString("preop.hierarchy.select", "join");
+                cs.putString("hierarchy.select", "Subordinate");
+            } else {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Invalid hierarchy provided");
+            }
+        }
+
+        // Database Panel
+        cs.putString("internaldb.ldapconn.host", data.getDsHost());
+        cs.putString("internaldb.ldapconn.port", data.getDsPort());
+        cs.putString("internaldb.database", data.getDatabase());
+        cs.putString("internaldb.basedn", data.getBaseDN());
+        cs.putString("internaldb.ldapauth.bindDN", data.getBindDN());
+        cs.putString("internaldb.ldapconn.secureConn", (data.getSecureConn().equals("on") ? "true" : "false"));
+        cs.putString("preop.database.removeData", data.getRemoveData());
+
+        try {
+            cs.commit(false);
+        } catch (EBaseException e2) {
+            e2.printStackTrace();
+            throw new CMSException("Unable to commit config parameters to file");
+        }
+
+        if (data.getIsClone().equals("true")) {
+            String masterhost = "";
+            String masterport = "";
+            String masterbasedn = "";
+            String realhostname = "";
+            try {
+                masterhost = cs.getString("preop.internaldb.master.ldapconn.host", "");
+                masterport = cs.getString("preop.internaldb.master.ldapconn.port", "");
+                masterbasedn = cs.getString("preop.internaldb.master.basedn", "");
+                realhostname = cs.getString("machineName", "");
+            } catch (Exception e) {
+            }
+
+            if (masterhost.equals(realhostname) && masterport.equals(data.getDsPort())) {
+                throw new CMSException(Response.Status.BAD_REQUEST,
+                        "Master and clone must not share the same internal database");
+            }
+
+            if (!masterbasedn.equals(data.getBaseDN())) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Master and clone should have the same base DN");
+            }
+
+            String masterReplicationPort = data.getMasterReplicationPort();
+            if ((masterReplicationPort != null) && (!masterReplicationPort.equals(""))) {
+                cs.putString("internaldb.ldapconn.masterReplicationPort", masterReplicationPort);
+            } else {
+                cs.putString("internaldb.ldapconn.masterReplicationPort", masterport);
+            }
+
+            String cloneReplicationPort = data.getCloneReplicationPort();
+            if ((cloneReplicationPort == null) || (cloneReplicationPort.length() == 0)) {
+                cloneReplicationPort = data.getDsPort();
+            }
+            cs.putString("internaldb.ldapconn.cloneReplicationPort", cloneReplicationPort);
+
+            String replicationSecurity = data.getReplicationSecurity();
+            if ((cloneReplicationPort == data.getDsPort()) && (data.getSecureConn().equals("on"))) {
+                replicationSecurity = "SSL";
+            } else if (replicationSecurity == null) {
+                replicationSecurity = "None";
+            }
+            cs.putString("internaldb.ldapconn.replicationSecurity", replicationSecurity);
+        }
+
+        try {
+            /* BZ 430745 create password for replication manager */
+            String replicationpwd = Integer.toString(new Random().nextInt());
+
+            IConfigStore psStore = null;
+            String passwordFile = null;
+            passwordFile = cs.getString("passwordFile");
+            psStore = CMS.createFileConfigStore(passwordFile);
+            psStore.putString("internaldb", data.getBindpwd());
+            psStore.putString("replicationdb", replicationpwd);
+            psStore.commit(false);
+
+            ConfigurationUtils.populateDB();
+
+            cs.putString("preop.internaldb.replicationpwd", replicationpwd);
+            cs.putString("preop.database.removeData", "false");
+            cs.commit(false);
+
+            ConfigurationUtils.reInitSubsystem(csType);
+            ConfigurationUtils.populateIndexes();
+
+            if (data.getIsClone().equals("true")) {
+                CMS.debug("Start setting up replication.");
+                ConfigurationUtils.setupReplication();
+                ConfigurationUtils.reInitSubsystem(csType);
+            }
+        } catch (Exception e) {
+            throw new CMSException("Error in populating database" + e);
+        }
+
+        // SizePanel, NamePanel, CertRequestPanel
+        //handle the CA URL
+        try {
+            if ((data.getHierarchy() == null) || (data.getHierarchy().equals("join"))) {
+                String url = data.getIssuingCA();
+                if (url.equals("External CA")) {
+                    CMS.debug("external CA selected");
+                    cs.putString("preop.ca.type", "otherca");
+                    cs.putString("preop.ca.pkcs7", "");
+                    cs.putInteger("preop.ca.certchain.size", 0);
+                    if (csType.equals("CA")) {
+                        cs.putString("preop.cert.signing.type", "remote");
+                    }
+                } else {
+                    CMS.debug("local CA selected");
+                    url = url.substring(url.indexOf("https"));
+                    cs.putString("preop.ca.url", url);
+
+                    URL urlx = new URL(url);
+                    String host = urlx.getHost();
+                    int port = urlx.getPort();
+                    int admin_port = ConfigurationUtils.getPortFromSecurityDomain(domainXML,
+                            host, port, "CA", "SecurePort", "SecureAdminPort");
+
+                    cs.putString("preop.ca.type", "sdca");
+                    cs.putString("preop.ca.hostname", host);
+                    cs.putInteger("preop.ca.httpsport", port);
+                    cs.putInteger("preop.ca.httpsadminport", admin_port);
+
+                    if (!data.getIsClone().equals("true")) {
+                       ConfigurationUtils.importCertChain(host, admin_port, "/ca/admin/ca/getCertChain", "ca");
+                    }
+
+                    if (csType.equals("CA")) {
+                        cs.putString("preop.cert.signing.type", "remote");
+                        cs.putString("preop.cert.signing.profile","caInstallCACert");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new CMSException("Error in obtaining certificate chain from issuing CA: " + e);
+        }
+
+        boolean hasSigningCert = false;
+        Vector<Cert> certs = new Vector<Cert>();
+        try {
+            StringTokenizer t = new StringTokenizer(certList, ",");
+            while (t.hasMoreTokens()) {
+                String ct = t.nextToken();
+                boolean enable = cs.getBoolean("preop.cert." + ct + ".enable", true);
+                if (!enable) continue;
+
+                Collection<CertData> certData = data.getSystemCerts();
+                Iterator<CertData> iterator = certData.iterator();
+                CertData cdata = null;
+                while (iterator.hasNext()) {
+                    cdata = iterator.next();
+                    if (cdata.getTag().equals(ct)) break;
+                }
+
+                String keytype = (cdata.getKeyType() != null) ? cdata.getKeyType() : "rsa";
+
+                String keyalgorithm = cdata.getKeyAlgorithm();
+                if (keyalgorithm == null) {
+                    keyalgorithm = (keytype.equals("ecc")) ? "SHA256withEC" : "SHA256withRSA";
+                }
+
+                String signingalgorithm = (cdata.getSigningAlgorithm() != null)?  cdata.getSigningAlgorithm(): keyalgorithm ;
+                String nickname = (cdata.getNickname() != null) ? cdata.getNickname() :
+                    cs.getString("preop.cert." + ct + ".nickname");
+                String dn = (cdata.getSubjectDN() != null)? cdata.getSubjectDN() :
+                    cs.getString("preop.cert." + ct + ".dn");
+
+
+                cs.putString("preop.cert." + ct + ".keytype", keytype);
+                cs.putString("preop.cert." + ct + ".keyalgorithm", keyalgorithm);
+                cs.putString("preop.cert." + ct + ".signingalgorithm", signingalgorithm);
+                cs.putString("preop.cert." + ct + ".nickname", nickname);
+                cs.putString("preop.cert." + ct + ".dn", dn);
+
+                if (data.getStepTwo() == null) {
+                    if (keytype.equals("ecc")) {
+                        String curvename = (cdata.getKeyCurveName() != null) ?
+                                cdata.getKeyCurveName() : cs.getString("keys.ecc.curve.default");
+                        cs.putString("preop.cert." + ct + ".curvename.name", curvename);
+                        ConfigurationUtils.createECCKeyPair(token, curvename, cs, ct);
+                    } else {
+                        String keysize = cdata.getKeySize() != null ? cdata.getKeySize() : cs
+                                .getString("keys.rsa.keysize.default");
+                        cs.putString("preop.cert." + ct + ".keysize.size", keysize);
+                        ConfigurationUtils.createRSAKeyPair(token, Integer.parseInt(keysize), cs, ct);
+                    }
+                } else {
+                    CMS.debug("configure(): step two selected.  keys will not be generated");
+                }
+
+                String tokenName = cdata.getToken() != null ? cdata.getToken() : token;
+                Cert certObj = new Cert(tokenName, nickname, ct);
+                certObj.setDN(dn);
+                certObj.setSubsystem(cs.getString("preop.cert." + ct + ".subsystem"));
+                certObj.setType(cs.getString("preop.cert." + ct + ".type"));
+
+                if (data.getStepTwo() == null) {
+                    ConfigurationUtils.configCert(null, null, null, certObj, null);
+                } else {
+                    String subsystem = cs.getString("preop.cert." + ct + ".subsystem");
+                    String certStr = cs.getString(subsystem + "." + ct + ".cert" );
+                    certObj.setCert(certStr);
+                    CMS.debug("Step 2: certStr for " + ct + " is " + certStr);
+                }
+                ConfigurationUtils.handleCertRequest(cs, ct, certObj);
+
+                if (data.getIsClone().equals("true")) {
+                    ConfigurationUtils.updateCloneConfig();
+                }
+
+                // to determine if we have the signing cert when using an external ca
+                // this will only execute on a ca
+                String b64 = cdata.getCert();
+                if (ct.equals("signing") && (b64!= null) && (b64.length()>0) && (!b64.startsWith("..."))) {
+                    hasSigningCert = true;
+                    if (data.getIssuingCA().equals("External CA")) {
+                        b64 = CryptoUtil.stripCertBrackets(b64.trim());
+                        certObj.setCert(CryptoUtil.normalizeCertStr(b64));
+
+                        if (cdata.getCertChain() != null) {
+                            certObj.setCertChain(cdata.getCertChain());
+                        } else {
+                            throw new CMSException(Response.Status.BAD_REQUEST, "CertChain not provided");
+                        }
+                    }
+                }
+
+                certs.addElement(certObj);
+            }
+            // make sure to commit changes here for step 1
+            cs.commit(false);
+
+        } catch (NumberFormatException e) {
+            // move these validations to validate()?
+            throw new CMSException(Response.Status.BAD_REQUEST, "Non-integer value for key size");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            throw new CMSException(Response.Status.BAD_REQUEST, "Invalid algorithm " + e);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CMSException("Error in setting certificate names and key sizes: " + e);
+        }
+
+        // submitting to external ca
+        if ((data.getIssuingCA()!= null) && data.getIssuingCA().equals("External CA") && (!hasSigningCert)) {
+            response.setSystemCerts(certs);
+            return response;
+        }
+
+        Enumeration<Cert> c = certs.elements();
+        while (c.hasMoreElements()) {
+            Cert cert = c.nextElement();
+            int ret;
+            try {
+                ret = ConfigurationUtils.handleCerts(cert);
+                ConfigurationUtils.setCertPermissions(cert.getCertTag());
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Error in confguring system certificates" + e);
+            }
+            if (ret != 0) {
+                throw new CMSException("Error in confguring system certificates");
+            }
+        }
+        response.setSystemCerts(certs);
+
+        // BackupKeyCertPanel/SavePKCS12Panel
+        if (data.getBackupKeys().equals("true")) {
+            try {
+                ConfigurationUtils.backupKeys(data.getBackupPassword(), data.getBackupFile());
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Error in creating pkcs12 to backup keys and certs: " + e);
+            }
+        }
+
+        // AdminPanel
+        if (!data.getIsClone().equals("true")) {
+            try {
+                X509CertImpl admincerts[] = new X509CertImpl[1];
+                ConfigurationUtils.createAdmin(data.getAdminUID(), data.getAdminEmail(),
+                        data.getAdminName(), data.getAdminPassword());
+                if (csType.equals("CA")) {
+                    ConfigurationUtils.createAdminCertificate(data.getAdminCertRequest(),
+                            data.getAdminCertRequestType(), data.getAdminSubjectDN());
+
+                    String serialno = cs.getString("preop.admincert.serialno.0");
+                    ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(ICertificateAuthority.ID);
+                    ICertificateRepository repo = ca.getCertificateRepository();
+                    admincerts[0] = repo.getX509Certificate(new BigInteger(serialno, 16));
+                } else {
+                    String type = cs.getString("preop.ca.type", "");
+                    String ca_hostname = "";
+                    int ca_port = -1;
+                    if (type.equals("sdca")) {
+                        ca_hostname = cs.getString("preop.ca.hostname");
+                        ca_port = cs.getInteger("preop.ca.httpsport");
+                    } else {
+                        ca_hostname = cs.getString("securitydomain.host", "");
+                        ca_port = cs.getInteger("securitydomain.httpseeport");
+                    }
+                    String b64 = ConfigurationUtils.submitAdminCertRequest(ca_hostname, ca_port,
+                            data.getAdminProfileID(), data.getAdminCertRequestType(),
+                            data.getAdminCertRequest(), data.getAdminSubjectDN());
+                    b64 = CryptoUtil.stripCertBrackets(b64.trim());
+                    byte[] b = CryptoUtil.base64Decode(b64);
+                    admincerts[0] = new X509CertImpl(b);
+                }
+                CMS.reinit(IUGSubsystem.ID);
+
+                IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(IUGSubsystem.ID);
+                IUser user = ug.getUser(data.getAdminUID());
+                user.setX509Certificates(admincerts);
+                ug.addUserCert(user);
+                response.setAdminCert(admincerts[0]);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Error in creating admin user: " + e);
+            }
+        }
+
+        // Done Panel
+        // Create or update security domain
+        try {
+            if (securityDomainType.equals(ConfigurationData.NEW_DOMAIN)) {
+                ConfigurationUtils.createSecurityDomain();
+            } else {
+                ConfigurationUtils.updateSecurityDomain();
+            }
+            cs.putString("service.securityDomainPort", CMS.getAgentPort());
+            cs.putString("securitydomain.store", "ldap");
+            cs.commit(false);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CMSException("Error while updating security domain: " + e);
+        }
+
+        // need to push connector information to the CA
+        String ca_host="";
+        try {
+            ca_host = cs.getString("preop.ca.hostname", "");
+        } catch (EBaseException e) {
+            e.printStackTrace();
+        }
+
+        // need to push connector information to the CA
+        try {
+            if (csType.equals("KRA") && (!ca_host.equals(""))) {
+                ConfigurationUtils.updateConnectorInfo(CMS.getAgentHost(), CMS.getAgentPort());
+                ConfigurationUtils.setupClientAuthUser();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CMSException("Errors in pushing KRA connector information to the CA: " + e);
+        }
+
+        // import the CA certificate into the OCSP
+        // configure the CRL Publishing to OCSP in CA
+        try {
+            if (csType.equals("OCSP") && (!ca_host.equals(""))) {
+                CMS.reinit(IOCSPAuthority.ID);
+                ConfigurationUtils.importCACertToOCSP();
+                ConfigurationUtils.updateOCSPConfig();
+                ConfigurationUtils.setupClientAuthUser();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CMSException("Errors in configuring CA publishing to OCSP: " + e);
+        }
+
+        if (!data.getIsClone().equals("true")) {
+            try {
+                if (csType.equals("CA") || csType.equals("KRA")) {
+                     ConfigurationUtils.updateNextRanges();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CMSException("Errors in updating nxt serial number ranges in DB: " + e);
+            }
+        }
+
+        try {
+            if (data.getIsClone().equals("true") && csType.equalsIgnoreCase("CA")
+                    && ConfigurationUtils.isSDHostDomainMaster(cs)) {
+                // cloning a domain master CA, the clone is also master of its domain
+                cs.putString("securitydomain.host", CMS.getEEHost());
+                cs.putString("securitydomain.httpport", CMS.getEENonSSLPort());
+                cs.putString("securitydomain.httpsadminport", CMS.getAdminPort());
+                cs.putString("securitydomain.httpsagentport", CMS.getAgentPort());
+                cs.putString("securitydomain.httpseeport", CMS.getEESSLPort());
+                cs.putString("securitydomain.select", "new");
+
+            }
+        } catch (Exception e1) {
+            e1.printStackTrace();
+            throw new CMSException("Errors in determining if security domain host is a master CA");
+        }
+
+        try {
+            String dbuser = csType + "-" + CMS.getEEHost() + "-" + CMS.getEESSLPort();
+            if (! securityDomainType.equals(ConfigurationData.NEW_DOMAIN)) {
+                ConfigurationUtils.setupDBUser(dbuser);
+            }
+            IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+            IUser user = system.getUser(dbuser);
+            system.addCertSubjectDN(user);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CMSException("Errors in creating or updating dbuser: " + e);
+        }
+
+        cs.putInteger("cs.state", 1);
+
+        // update serial numbers for clones
+
+        // save some variables, remove remaining preops
+        try {
+            ConfigurationUtils.removePreopConfigEntries();
+        } catch (EBaseException e) {
+            e.printStackTrace();
+            throw new CMSException("Errors when removing preop config entries: " + e);
+        }
+
+        // Create an empty file that designates the fact that although
+        // this server instance has been configured, it has NOT yet
+        // been restarted!
+        String restart_server = instanceRoot + "/conf/" + RESTART_SERVER_AFTER_CONFIGURATION;
+        Utils.exec("touch " + restart_server);
+        Utils.exec("chmod 00660 " + restart_server);
+
+        response.setStatus(SUCCESS);
+        return response;
+    }
+
+    private void validateData(ConfigurationData data) {
+        // get required info from CS.cfg
+        String preopPin;
+        try {
+            preopPin = cs.getString("preop.pin");
+        } catch (Exception e) {
+            CMS.debug("validateData: Failed to get required config form CS.cfg");
+            e.printStackTrace();
+            throw new CMSException("Unable to retrieve required configuration from configuration files");
+        }
+
+        // get the preop pin and validate it
+        String pin = data.getPin();
+        if (pin == null) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "No preop pin provided");
+        }
+        if (!preopPin.equals(pin)) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Incorrect pin provided");
+        }
+
+        // validate security domain settings
+        String domainType = data.getSecurityDomainType();
+        if (domainType == null) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Security Domain Type not provided");
+        }
+
+        if (domainType.equals(ConfigurationData.NEW_DOMAIN)) {
+            if (!csType.equals("CA")) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "New Domain is only valid for CA subsytems");
+            }
+            if (data.getSecurityDomainName() == null) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Security Domain Name is not provided");
+            }
+        } else if (domainType.equals(ConfigurationData.EXISTING_DOMAIN)) {
+            String domainURI = data.getSecurityDomainUri();
+            if (domainURI == null) {
+                throw new CMSException(Response.Status.BAD_REQUEST,
+                        "Existing security domain requested, but no security domain URI provided");
+            }
+
+            try {
+                @SuppressWarnings("unused")
+                URL admin_u = new URL(domainURI);  // check for invalid URL
+            } catch (MalformedURLException e) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Invalid security domain URI");
+            }
+            if ((data.getSecurityDomainUser() == null) || (data.getSecurityDomainPassword() == null)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Security domain user or password not provided");
+            }
+
+        } else {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Invalid security domain URI provided");
+        }
+
+        if ((data.getSubsystemName() == null) || (data.getSubsystemName().length() ==0)) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Invalid or no subsystem name provided");
+        }
+
+        if (data.getIsClone().equals("true")) {
+            String cloneUri = data.getCloneUri();
+            if (cloneUri == null) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Clone selected, but no clone URI provided");
+            }
+            try {
+                @SuppressWarnings("unused")
+                URL url = new URL(cloneUri); // check for invalid URL
+                // confirm protocol is https
+            } catch (MalformedURLException e) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Invalid clone URI");
+            }
+
+            if (data.getToken().equals(ConfigurationData.TOKEN_DEFAULT)) {
+                if (data.getP12File() == null) {
+                    throw new CMSException(Response.Status.BAD_REQUEST, "P12 filename not provided");
+                }
+
+                if (data.getP12Password() == null) {
+                    throw new CMSException(Response.Status.BAD_REQUEST, "P12 password not provided");
+                }
+            }
+        }
+
+        String dsHost = data.getDsHost();
+        if (dsHost == null || dsHost.length() == 0) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Internal database host not provided");
+        }
+
+        try {
+            Integer.parseInt(data.getDsPort());  // check for errors
+        } catch (NumberFormatException e) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Internal database port is invalid");
+        }
+
+        String basedn = data.getBaseDN();
+        if (basedn == null || basedn.length() == 0) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Internal database basedn not provided");
+        }
+
+        String binddn = data.getBindDN();
+        if (binddn == null || binddn.length() == 0) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Internal database basedn not provided");
+        }
+
+        String database = data.getDatabase();
+        if (database == null || database.length() == 0) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Internal database database name not provided");
+        }
+
+        String bindpwd = data.getBindpwd();
+        if (bindpwd == null || bindpwd.length() == 0) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Internal database database name not provided");
+        }
+
+        String masterReplicationPort = data.getMasterReplicationPort();
+        if (masterReplicationPort != null && masterReplicationPort.length() > 0) {
+            try {
+                Integer.parseInt(masterReplicationPort); // check for errors
+            } catch (NumberFormatException e) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Master replication port is invalid");
+            }
+        }
+
+        String cloneReplicationPort = data.getCloneReplicationPort();
+        if (cloneReplicationPort != null && cloneReplicationPort.length() > 0) {
+            try {
+                Integer.parseInt(cloneReplicationPort); // check for errors
+            } catch (Exception e) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Clone replication port is invalid");
+            }
+        }
+
+        if ((data.getBackupKeys() != null) && data.getBackupKeys().equals("true")) {
+            if ((data.getBackupFile() == null) || (data.getBackupFile().length()<=0)) {
+                //TODO: also check for valid path, perhaps by touching file there
+                throw new CMSException(Response.Status.BAD_REQUEST, "Invalid key backup file name");
+            }
+
+            if ((data.getBackupPassword() == null) || (data.getBackupPassword().length()<=8)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "key backup password must be at least 8 characters");
+            }
+        }
+
+        if (csType.equals("CA") && (data.getHierarchy() == null)) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Hierarchy is requred for CA, not provided");
+        }
+
+        if (data.getIsClone().equals("false")) {
+            if ((data.getAdminUID() == null) || (data.getAdminUID().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin UID not provided");
+            }
+            if ((data.getAdminPassword() == null) || (data.getAdminPassword().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin Password not provided");
+            }
+            if ((data.getAdminEmail() == null) || (data.getAdminEmail().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin UID not provided");
+            }
+            if ((data.getAdminName() == null) || (data.getAdminName().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin name not provided");
+            }
+            if ((data.getAdminCertRequest() == null) || (data.getAdminCertRequest().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin cert request not provided");
+            }
+            if ((data.getAdminCertRequestType() == null) || (data.getAdminCertRequestType().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin cert request type not provided");
+            }
+            if ((data.getAdminSubjectDN() == null) || (data.getAdminSubjectDN().length()==0)) {
+                throw new CMSException(Response.Status.BAD_REQUEST, "Admin subjectDN not provided");
+            }
+        }
+
+    }
+
+    @Override
+    public InstallToken getInstallToken(InstallTokenRequest data) {
+        // TODO Figure out how to do authentication here based on user/pass
+        // For now, allow all user/pass to be valid
+        CMS.debug("getInstallToken(): starting");
+        String user = data.getUser();
+        String host = data.getHost();
+        String subsystem = data.getSubsystem();
+        String groupname = ConfigurationUtils.getGroupName(user, subsystem);
+
+        // assign cookie
+        long num = mRandom.nextLong();
+        String cookie = num + "";
+        ISecurityDomainSessionTable ctable = CMS.getSecurityDomainSessionTable();
+        String ip;
+        try {
+            ip = InetAddress.getByName(host).toString();
+        } catch (UnknownHostException e) {
+            throw new CMSException(Response.Status.BAD_REQUEST, "Unable to resolve host " + host +
+                    "to an IP address: " + e);
+        }
+        int index = ip.indexOf("/");
+        if (index > 0)  ip = ip.substring(index + 1);
+
+        ctable.addEntry(cookie, ip, user, groupname);
+
+        return new InstallToken(cookie);
+    }
+
+    @Override
+    public DomainInfo getDomainInfo() {
+        // TODO Auto-generated method stub for a RESTful method that returns the security domain
+        return null;
+    }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9e5e8005b7cc14be59cb8eab47b61bec4e2ea97
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java
@@ -0,0 +1,270 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+ 
+package com.netscape.cms.servlet.csadmin.model;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="CertData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CertData {
+    public static final String TAG = "tag";
+    public static final String NICKNAME = "nickname";
+    public static final String TOKEN = "token";
+    public static final String KEY_TYPE = "keyType";
+    public static final String KEY_ALGORITHM = "keyAlgorithm";
+    public static final String SIGNING_ALGORITHM = "signingAlgorithm";    
+    public static final String KEY_SIZE = "keySize";
+    public static final String KEY_CURVENAME = "keyCurveName";
+    public static final String REQUEST = "request";
+    public static final String SUBJECT_DN = "subjectDN";
+    public static final String CERT = "cert";
+    public static final String CERT_CHAIN = "certChain";
+    
+    @XmlElement
+    protected String tag;
+    
+    @XmlElement
+    protected String nickname;
+    
+    @XmlElement
+    protected String token;
+    
+    @XmlElement
+    protected String keyType;
+    
+    @XmlElement
+    protected String keyAlgorithm;
+    
+    @XmlElement
+    protected String signingAlgorithm;
+    
+    @XmlElement
+    protected String keySize;
+    
+    @XmlElement
+    protected String keyCurveName;
+    
+    @XmlElement
+    protected String request;
+    
+    @XmlElement
+    protected String subjectDN;
+    
+    @XmlElement
+    protected String cert;
+    
+    @XmlElement
+    protected String certChain;
+    
+    public CertData() {
+        // required for JAXB
+    }
+    
+    public CertData(MultivaluedMap<String, String> form) {
+        tag = form.getFirst(TAG);
+        nickname = form.getFirst(NICKNAME);
+        token = form.getFirst(TOKEN);
+        keyType = form.getFirst(KEY_TYPE);
+        keyAlgorithm = form.getFirst(KEY_ALGORITHM);
+        signingAlgorithm = form.getFirst(SIGNING_ALGORITHM);
+        keySize = form.getFirst(KEY_SIZE);
+        keyCurveName = form.getFirst(KEY_CURVENAME);
+        request = form.getFirst(REQUEST);
+        subjectDN = form.getFirst(SUBJECT_DN);
+        cert = form.getFirst(CERT);
+        certChain = form.getFirst(CERT_CHAIN);
+    }
+
+    /**
+     * @return the tag
+     */
+    public String getTag() {
+        return tag;
+    }
+
+    /**
+     * @param tag the tag to set
+     */
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
+
+    /**
+     * @return the nickname
+     */
+    public String getNickname() {
+        return nickname;
+    }
+
+    /**
+     * @param nickname the nickname to set
+     */
+    public void setNickname(String nickname) {
+        this.nickname = nickname;
+    }
+
+    /**
+     * @return the token
+     */
+    public String getToken() {
+        return token;
+    }
+
+    /**
+     * @param token the token to set
+     */
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    /**
+     * @return the keyType
+     */
+    public String getKeyType() {
+        return keyType;
+    }
+
+    /**
+     * @param keyType the keyType to set
+     */
+    public void setKeyType(String keyType) {
+        this.keyType = keyType;
+    }
+
+    /**
+     * @return the keyAlgorithm
+     */
+    public String getKeyAlgorithm() {
+        return keyAlgorithm;
+    }
+
+    /**
+     * @param keyAlgorithm the keyAlgorithm to set
+     */
+    public void setKeyAlgorithm(String keyAlgorithm) {
+        this.keyAlgorithm = keyAlgorithm;
+    }
+
+    /**
+     * @return the signingAlgorithm
+     */
+    public String getSigningAlgorithm() {
+        return signingAlgorithm;
+    }
+
+    /**
+     * @param signingAlgorithm the signingAlgorithm to set
+     */
+    public void setSigningAlgorithm(String signingAlgorithm) {
+        this.signingAlgorithm = signingAlgorithm;
+    }
+
+    /**
+     * @return the keySize
+     */
+    public String getKeySize() {
+        return keySize;
+    }
+
+    /**
+     * @param keySize the keySize to set
+     */
+    public void setKeySize(String keySize) {
+        this.keySize = keySize;
+    }
+
+    /**
+     * @return the keyCurveName
+     */
+    public String getKeyCurveName() {
+        return keyCurveName;
+    }
+
+    /**
+     * @param keyCurveName the keyCurveName to set
+     */
+    public void setKeyCurveName(String keyCurveName) {
+        this.keyCurveName = keyCurveName;
+    }
+
+    /**
+     * @return the request
+     */
+    public String getRequest() {
+        return request;
+    }
+
+    /**
+     * @param request the request to set
+     */
+    public void setRequest(String request) {
+        this.request = request;
+    }
+
+    /**
+     * @return the subjectDN
+     */
+    public String getSubjectDN() {
+        return subjectDN;
+    }
+
+    /**
+     * @param subjectDN the subjectDN to set
+     */
+    public void setSubjectDN(String subjectDN) {
+        this.subjectDN = subjectDN;
+    }
+
+    /**
+     * @return the cert
+     */
+    public String getCert() {
+        return cert;
+    }
+
+    /**
+     * @param cert the cert to set
+     */
+    public void setCert(String cert) {
+        this.cert = cert;
+    }
+
+    /**
+     * @return the certChain
+     */
+    public String getCertChain() {
+        return certChain;
+    }
+
+    /**
+     * @param certChain the certChain to set
+     */
+    public void setCertChain(String certChain) {
+        this.certChain = certChain;
+    }
+    
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c1bea86b9426b5a2ecbd9517dfdca0d576592c5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java
@@ -0,0 +1,724 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin.model;
+
+import java.util.Collection;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="ConfigurationData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ConfigurationData {
+    private static final String PIN = "pin";
+    private static final String TOKEN = "token";
+    private static final String TOKEN_PASSWORD = "tokenPassword";
+    private static final String SECURITY_DOMAIN_TYPE = "securityDomainType";
+    private static final String SECURITY_DOMAIN_URI = "securityDomainUri";
+    private static final String SECURITY_DOMAIN_NAME = "securityDomainName";
+    private static final String SECURITY_DOMAIN_USER = "securityDomainUser";
+    private static final String SECURITY_DOMAIN_PASSWORD = "securityDomainPassword";
+    private static final String IS_CLONE = "isClone";
+    private static final String CLONE_URI = "cloneUri";
+    private static final String SUBSYSTEM_NAME = "subsystemName";
+    private static final String P12_FILE = "p12File";
+    private static final String P12_PASSWORD = "p12Password";
+    private static final String HIERARCHY = "hierarchy";
+    private static final String DSHOST = "dsHost";
+    private static final String DSPORT = "dsPort";
+    private static final String BASEDN = "basedn";
+    private static final String BINDDN = "binddn";
+    private static final String DATABASE = "database";
+    private static final String SECURECONN = "secureConn";
+    private static final String REMOVEDATA = "removeData";
+    private static final String MASTER_REPLICATION_PORT = "masterReplicationPort";
+    private static final String CLONE_REPLICATION_PORT = "cloneReplicationPort";
+    private static final String REPLICATION_SECURITY = "replicationSecurity";
+    private static final String ISSUING_CA = "issuingCa";
+    private static final String BACKUP_KEYS = "backupKeys";
+    private static final String BACKUP_FILE = "backupFile";
+    private static final String BACKUP_PASSWORD = "backupPassword";
+    private static final String ADMIN_UID = "adminUid";
+    private static final String ADMIN_EMAIL = "adminEmail";
+    private static final String ADMIN_PASSWORD = "adminPassword";
+    private static final String ADMIN_CERT_REQUEST = "adminCertRequest";
+    private static final String ADMIN_CERT_REQUEST_TYPE = "adminCertRequestType";
+    private static final String ADMIN_SUBJECT_DN = "adminSubjectDN";
+    private static final String ADMIN_NAME = "adminName";
+    private static final String ADMIN_PROFILE_ID = "adminProfileID";
+    private static final String STEP_TWO = "stepTwo";
+
+    //defaults
+    public static final String TOKEN_DEFAULT = "Internal Key Storage Token";
+    public static final String NEW_DOMAIN = "newdomain";
+    public static final String EXISTING_DOMAIN = "existingdomain";
+
+    @XmlElement
+    protected String pin;
+
+    @XmlElement(defaultValue=TOKEN_DEFAULT)
+    protected String token;
+
+    @XmlElement
+    protected String tokenPassword;
+
+    @XmlElement
+    protected String securityDomainType;
+
+    @XmlElement
+    protected String securityDomainUri;
+
+    @XmlElement
+    protected String securityDomainName;
+
+    @XmlElement
+    protected String securityDomainUser;
+
+    @XmlElement
+    protected String securityDomainPassword;
+
+    @XmlElement(defaultValue="false")
+    protected String isClone;
+
+    @XmlElement
+    protected String cloneUri;
+
+    @XmlElement
+    protected String subsystemName;
+
+    @XmlElement
+    protected String p12File;
+
+    @XmlElement
+    protected String p12Password;
+
+    @XmlElement
+    protected String hierarchy;
+
+    @XmlElement
+    protected String dsHost;
+
+    @XmlElement
+    protected String dsPort;
+
+    @XmlElement
+    protected String baseDN;
+
+    @XmlElement
+    protected String bindDN;
+
+    @XmlElement
+    protected String bindpwd;
+
+    @XmlElement
+    protected String database;
+
+    @XmlElement(defaultValue = "off")
+    protected String secureConn;
+
+    @XmlElement
+    protected String removeData;
+
+    @XmlElement
+    protected String masterReplicationPort;
+
+    @XmlElement
+    protected String cloneReplicationPort;
+
+    @XmlElement
+    protected String replicationSecurity;
+
+    @XmlElementRef
+    protected Collection<CertData> systemCerts;
+
+    @XmlElement
+    protected String issuingCA;
+
+    @XmlElement
+    protected String backupKeys;
+
+    @XmlElement
+    protected String backupPassword;
+
+    @XmlElement
+    protected String backupFile;
+
+    @XmlElement
+    protected String adminUID;
+
+    @XmlElement
+    protected String adminPassword;
+
+    @XmlElement
+    protected String adminEmail;
+
+    @XmlElement
+    protected String adminCertRequest;
+
+    @XmlElement
+    protected String adminCertRequestType;
+
+    @XmlElement
+    protected String adminSubjectDN;
+
+    @XmlElement
+    protected String adminName;
+
+    @XmlElement
+    protected String adminProfileID;
+
+    @XmlElement
+    protected String stepTwo;
+
+    public ConfigurationData() {
+        // required for JAXB
+    }
+
+    public ConfigurationData(MultivaluedMap<String, String> form) {
+        pin = form.getFirst(PIN);
+        token = form.getFirst(TOKEN);
+        tokenPassword = form.getFirst(TOKEN_PASSWORD);
+        securityDomainType = form.getFirst(SECURITY_DOMAIN_TYPE);
+        securityDomainUri = form.getFirst(SECURITY_DOMAIN_URI);
+        securityDomainName = form.getFirst(SECURITY_DOMAIN_NAME);
+        securityDomainUser = form.getFirst(SECURITY_DOMAIN_USER);
+        securityDomainPassword = form.getFirst(SECURITY_DOMAIN_PASSWORD);
+        isClone = form.getFirst(IS_CLONE);
+        cloneUri = form.getFirst(CLONE_URI);
+        subsystemName = form.getFirst(SUBSYSTEM_NAME);
+        p12File = form.getFirst(P12_FILE);
+        p12Password = form.getFirst(P12_PASSWORD);
+        hierarchy = form.getFirst(HIERARCHY);
+        dsHost = form.getFirst(DSHOST);
+        dsPort = form.getFirst(DSPORT);
+        baseDN = form.getFirst(BASEDN);
+        bindDN = form.getFirst(BINDDN);
+        database = form.getFirst(DATABASE);
+        secureConn = form.getFirst(SECURECONN);
+        removeData = form.getFirst(REMOVEDATA);
+        masterReplicationPort = form.getFirst(MASTER_REPLICATION_PORT);
+        cloneReplicationPort = form.getFirst(CLONE_REPLICATION_PORT);
+        replicationSecurity = form.getFirst(REPLICATION_SECURITY);
+        //TODO - figure out how to get the cert requests
+        issuingCA = form.getFirst(ISSUING_CA);
+        backupFile = form.getFirst(BACKUP_FILE);
+        backupPassword = form.getFirst(BACKUP_PASSWORD);
+        backupKeys = form.getFirst(BACKUP_KEYS);
+        adminUID = form.getFirst(ADMIN_UID);
+        adminEmail = form.getFirst(ADMIN_EMAIL);
+        adminPassword = form.getFirst(ADMIN_PASSWORD);
+        adminCertRequest = form.getFirst(ADMIN_CERT_REQUEST);
+        adminCertRequestType = form.getFirst(ADMIN_CERT_REQUEST_TYPE);
+        adminSubjectDN = form.getFirst(ADMIN_SUBJECT_DN);
+        adminName = form.getFirst(ADMIN_NAME);
+        adminProfileID = form.getFirst(ADMIN_PROFILE_ID);
+        stepTwo = form.getFirst(STEP_TWO);
+    }
+
+
+    public String getSubsystemName() {
+        return subsystemName;
+    }
+
+    public void setSubsystemName(String subsystemName) {
+        this.subsystemName = subsystemName;
+    }
+
+    public String getPin() {
+        return pin;
+    }
+
+    public void setPin(String pin) {
+        this.pin = pin;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public String getSecurityDomainType() {
+        return securityDomainType;
+    }
+
+    public void setSecurityDomainType(String securityDomainType) {
+        this.securityDomainType = securityDomainType;
+    }
+
+    public String getSecurityDomainUri() {
+        return securityDomainUri;
+    }
+
+    public void setSecurityDomainUri(String securityDomainUri) {
+        this.securityDomainUri = securityDomainUri;
+    }
+
+    public String getSecurityDomainName() {
+        return securityDomainName;
+    }
+
+    public void setSecurityDomainName(String securityDomainName) {
+        this.securityDomainName = securityDomainName;
+    }
+
+    public String getSecurityDomainUser() {
+        return securityDomainUser;
+    }
+
+    public void setSecurityDomainUser(String securityDomainUser) {
+        this.securityDomainUser = securityDomainUser;
+    }
+
+    public String getSecurityDomainPassword() {
+        return securityDomainPassword;
+    }
+
+    public void setSecurityDomainPassword(String securityDomainPassword) {
+        this.securityDomainPassword = securityDomainPassword;
+    }
+
+    public String getIsClone() {
+        return isClone;
+    }
+
+    public void setIsClone(String isClone) {
+        this.isClone = isClone;
+    }
+
+    public String getCloneUri() {
+        return cloneUri;
+    }
+
+    public void setCloneUri(String cloneUri) {
+        this.cloneUri = cloneUri;
+    }
+
+    /**
+     * @return the p12File
+     */
+    public String getP12File() {
+        return p12File;
+    }
+
+    /**
+     * @param p12File the p12File to set
+     */
+    public void setP12File(String p12File) {
+        this.p12File = p12File;
+    }
+
+    /**
+     * @return the p12Password
+     */
+    public String getP12Password() {
+        return p12Password;
+    }
+
+    /**
+     * @param p12Password the p12Password to set
+     */
+    public void setP12Password(String p12Password) {
+        this.p12Password = p12Password;
+    }
+
+    /**
+     * @return the tokenPassword
+     */
+    public String getTokenPassword() {
+        return tokenPassword;
+    }
+
+    /**
+     * @param tokenPassword the tokenPassword to set
+     */
+    public void setTokenPassword(String tokenPassword) {
+        this.tokenPassword = tokenPassword;
+    }
+
+    /**
+     * @return the hierarchy
+     */
+    public String getHierarchy() {
+        return hierarchy;
+    }
+
+    /**
+     * @param hierarchy the hierarchy to set
+     */
+    public void setHierarchy(String hierarchy) {
+        this.hierarchy = hierarchy;
+    }
+
+    /**
+     * @return the dsHost
+     */
+    public String getDsHost() {
+        return dsHost;
+    }
+
+    /**
+     * @param dsHost the dsHost to set
+     */
+    public void setDsHost(String dsHost) {
+        this.dsHost = dsHost;
+    }
+
+    /**
+     * @return the dsPort
+     */
+    public String getDsPort() {
+        return dsPort;
+    }
+
+    /**
+     * @param dsPort the dsPort to set
+     */
+    public void setDsPort(String dsPort) {
+        this.dsPort = dsPort;
+    }
+
+    /**
+     * @return the baseDN
+     */
+    public String getBaseDN() {
+        return baseDN;
+    }
+
+    /**
+     * @param baseDN the baseDN to set
+     */
+    public void setBaseDN(String baseDN) {
+        this.baseDN = baseDN;
+    }
+
+    /**
+     * @return the bindDN
+     */
+    public String getBindDN() {
+        return bindDN;
+    }
+
+    /**
+     * @param bindDN the bindDN to set
+     */
+    public void setBindDN(String bindDN) {
+        this.bindDN = bindDN;
+    }
+
+    /**
+     * @return the bindpwd
+     */
+    public String getBindpwd() {
+        return bindpwd;
+    }
+
+    /**
+     * @param bindpwd the bindpwd to set
+     */
+    public void setBindpwd(String bindpwd) {
+        this.bindpwd = bindpwd;
+    }
+
+    /**
+     * @return the secureConn
+     */
+    public String getSecureConn() {
+        return secureConn;
+    }
+
+    /**
+     * @param secureConn the secureConn to set
+     */
+    public void setSecureConn(String secureConn) {
+        this.secureConn = secureConn;
+    }
+
+    /**
+     * @return the removeData
+     */
+    public String getRemoveData() {
+        return removeData;
+    }
+
+    /**
+     * @param removeData the removeData to set
+     */
+    public void setRemoveData(String removeData) {
+        this.removeData = removeData;
+    }
+
+    /**
+     * @return the masterReplicationPort
+     */
+    public String getMasterReplicationPort() {
+        return masterReplicationPort;
+    }
+
+    /**
+     * @param masterReplicationPort the masterReplicationPort to set
+     */
+    public void setMasterReplicationPort(String masterReplicationPort) {
+        this.masterReplicationPort = masterReplicationPort;
+    }
+
+    /**
+     * @return the cloneReplicationPort
+     */
+    public String getCloneReplicationPort() {
+        return cloneReplicationPort;
+    }
+
+    /**
+     * @param cloneReplicationPort the cloneReplicationPort to set
+     */
+    public void setCloneReplicationPort(String cloneReplicationPort) {
+        this.cloneReplicationPort = cloneReplicationPort;
+    }
+
+    /**
+     * @return the replicationSecurity
+     */
+    public String getReplicationSecurity() {
+        return replicationSecurity;
+    }
+
+    /**
+     * @param replicationSecurity the replicationSecurity to set
+     */
+    public void setReplicationSecurity(String replicationSecurity) {
+        this.replicationSecurity = replicationSecurity;
+    }
+
+    /**
+     * @return the database
+     */
+    public String getDatabase() {
+        return database;
+    }
+
+    /**
+     * @param database the database to set
+     */
+    public void setDatabase(String database) {
+        this.database = database;
+    }
+
+    /**
+     *
+     * @return systemCerts
+     */
+    public Collection<CertData> getSystemCerts() {
+        return systemCerts;
+    }
+
+    /**
+     *
+     * @param systemCerts
+     */
+    public void setSystemCerts(Collection<CertData> systemCerts) {
+        this.systemCerts = systemCerts;
+    }
+
+    /**
+     * @return the issuingCA
+     */
+    public String getIssuingCA() {
+        return issuingCA;
+    }
+
+    /**
+     * @param issuingCA the issuingCA to set
+     */
+    public void setIssuingCA(String issuingCA) {
+        this.issuingCA = issuingCA;
+    }
+
+    /**
+     * @return the backupKeys
+     */
+    public String getBackupKeys() {
+        return backupKeys;
+    }
+
+    /**
+     * @param backupKeys the backupKeys to set
+     */
+    public void setBackupKeys(String backupKeys) {
+        this.backupKeys = backupKeys;
+    }
+
+    /**
+     * @return the backupFile
+     */
+    public String getBackupFile() {
+        return backupFile;
+    }
+
+    /**
+     * @param backupFile the backupFile to set
+     */
+    public void setBackupFile(String backupFile) {
+        this.backupFile = backupFile;
+    }
+
+    /**
+     * @return the backupPassword
+     */
+    public String getBackupPassword() {
+        return backupPassword;
+    }
+
+    /**
+     * @param backupPassword the backupPassword to set
+     */
+    public void setBackupPassword(String backupPassword) {
+        this.backupPassword = backupPassword;
+    }
+
+    /**
+     * @return the adminUID
+     */
+    public String getAdminUID() {
+        return adminUID;
+    }
+
+    /**
+     * @param adminUID the adminUID to set
+     */
+    public void setAdminUID(String adminUID) {
+        this.adminUID = adminUID;
+    }
+
+    /**
+     * @return the adminPassword
+     */
+    public String getAdminPassword() {
+        return adminPassword;
+    }
+
+    /**
+     * @param adminPassword the adminPassword to set
+     */
+    public void setAdminPassword(String adminPassword) {
+        this.adminPassword = adminPassword;
+    }
+
+    /**
+     * @return the adminEmail
+     */
+    public String getAdminEmail() {
+        return adminEmail;
+    }
+
+    /**
+     * @param adminEmail the adminEmail to set
+     */
+    public void setAdminEmail(String adminEmail) {
+        this.adminEmail = adminEmail;
+    }
+
+    /**
+     * @return the adminCertRequest
+     */
+    public String getAdminCertRequest() {
+        return adminCertRequest;
+    }
+
+    /**
+     * @param adminCertRequest the adminCertRequest to set
+     */
+    public void setAdminCertRequest(String adminCertRequest) {
+        this.adminCertRequest = adminCertRequest;
+    }
+
+    /**
+     * @return the adminCertRequestType
+     */
+    public String getAdminCertRequestType() {
+        return adminCertRequestType;
+    }
+
+    /**
+     * @param adminCertRequestType the adminCertRequestType to set
+     */
+    public void setAdminCertRequestType(String adminCertRequestType) {
+        this.adminCertRequestType = adminCertRequestType;
+    }
+
+    /**
+     * @return the adminSubjectDN
+     */
+    public String getAdminSubjectDN() {
+        return adminSubjectDN;
+    }
+
+    /**
+     * @param adminSubjectDN the adminSubjectDN to set
+     */
+    public void setAdminSubjectDN(String adminSubjectDN) {
+        this.adminSubjectDN = adminSubjectDN;
+    }
+
+    /**
+     * @return the adminName
+     */
+    public String getAdminName() {
+        return adminName;
+    }
+
+    /**
+     * @param adminName the adminName to set
+     */
+    public void setAdminName(String adminName) {
+        this.adminName = adminName;
+    }
+
+    /**
+     * @return the adminProfileID
+     */
+    public String getAdminProfileID() {
+        return adminProfileID;
+    }
+
+    /**
+     * @param adminProfileID the adminProfileID to set
+     */
+    public void setAdminProfileID(String adminProfileID) {
+        this.adminProfileID = adminProfileID;
+    }
+
+    public String getStepTwo() {
+        return stepTwo;
+    }
+
+    public void setStepTwo(String stepTwo) {
+        this.stepTwo = stepTwo;
+    }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1656fddaa9f5103a43a0ef20ea64ce4b889c988
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+package com.netscape.cms.servlet.csadmin.model;
+
+import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Vector;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.csadmin.Cert;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="ConfigurationResponseData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ConfigurationResponseData {
+    
+    @XmlElementRef
+    protected Collection<CertData> systemCerts;
+    
+    @XmlElement
+    protected CertData adminCert;
+    
+    @XmlElement
+    protected String status;
+    
+    public ConfigurationResponseData() {
+        systemCerts = new ArrayList<CertData>();
+        adminCert = new CertData();
+    }
+    
+    public void setSystemCerts(Vector<Cert> certs) {
+        systemCerts.clear();
+        Enumeration<Cert> e = certs.elements();
+        while (e.hasMoreElements()) {
+            Cert cert = e.nextElement();
+            CertData cdata = new CertData();
+            cdata.setCert(cert.getCert());
+            cdata.setRequest(cert.getRequest());
+            cdata.setTag(cert.getCertTag());
+            cdata.setCertChain(cert.getCertChain());
+            systemCerts.add(cdata);
+        }
+    }
+    
+    /**
+     * @return the systemCerts
+     */
+    public Collection<CertData> getSystemCerts() {
+        return systemCerts;
+    }
+
+    /**
+     * @param systemCerts the systemCerts to set
+     */
+    public void setSystemCerts(Collection<CertData> systemCerts) {
+        this.systemCerts = systemCerts;
+    }
+
+    /**
+     * @return the adminCert
+     */
+    public CertData getAdminCert() {
+        return adminCert;
+    }
+
+    /**
+     * @param adminCert the adminCert to set
+     */
+    public void setAdminCert(CertData adminCert) {
+        this.adminCert = adminCert;
+    }
+
+    /**
+     * @return the status
+     */
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * @param status the status to set
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+
+
+    public void setAdminCert(X509CertImpl x509CertImpl) throws CertificateEncodingException {
+        adminCert.setCert(CMS.BtoA(x509CertImpl.getEncoded()));
+    }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ba351cb1e1d20c3704eb9072a9d0d242f7fdf5d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java
@@ -0,0 +1,155 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+package com.netscape.cms.servlet.csadmin.model;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="DomainInfo")
+public class DomainInfo {
+    
+    @XmlElement(name="CAList")
+    protected SecurityDomainHostList caList;
+    
+    @XmlElement(name="KRAList")
+    protected SecurityDomainHostList kraList;
+    
+    @XmlElement(name="OCSPList")
+    protected SecurityDomainHostList ocspList;
+    
+    @XmlElement(name="TKSList")
+    protected SecurityDomainHostList tksList;
+    
+    @XmlElement(name="TPSList")
+    protected SecurityDomainHostList tpsList;
+    
+    @XmlElement(name="RAList")
+    protected SecurityDomainHostList raList;
+    
+    @XmlElement
+    protected String name;
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the caList
+     */
+    public SecurityDomainHostList getCaList() {
+        return caList;
+    }
+
+    /**
+     * @param caList the caList to set
+     */
+    public void setCaList(SecurityDomainHostList caList) {
+        this.caList = caList;
+    }
+
+    /**
+     * @return the kraList
+     */
+    public SecurityDomainHostList getKraList() {
+        return kraList;
+    }
+
+    /**
+     * @param kraList the kraList to set
+     */
+    public void setKraList(SecurityDomainHostList kraList) {
+        this.kraList = kraList;
+    }
+
+    /**
+     * @return the ocspList
+     */
+    public SecurityDomainHostList getOcspList() {
+        return ocspList;
+    }
+
+    /**
+     * @param ocspList the ocspList to set
+     */
+    public void setOcspList(SecurityDomainHostList ocspList) {
+        this.ocspList = ocspList;
+    }
+
+    /**
+     * @return the tksList
+     */
+    public SecurityDomainHostList getTksList() {
+        return tksList;
+    }
+
+    /**
+     * @param tksList the tksList to set
+     */
+    public void setTksList(SecurityDomainHostList tksList) {
+        this.tksList = tksList;
+    }
+
+    /**
+     * @return the tpsList
+     */
+    public SecurityDomainHostList getTpsList() {
+        return tpsList;
+    }
+
+    /**
+     * @param tpsList the tpsList to set
+     */
+    public void setTpsList(SecurityDomainHostList tpsList) {
+        this.tpsList = tpsList;
+    }
+
+    /**
+     * @return the raList
+     */
+    public SecurityDomainHostList getRaList() {
+        return raList;
+    }
+
+    /**
+     * @param raList the raList to set
+     */
+    public void setRaList(SecurityDomainHostList raList) {
+        this.raList = raList;
+    }
+
+     
+    
+    
+    
+     
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java
new file mode 100644
index 0000000000000000000000000000000000000000..59284de37911f6c3472746ce0ef7e99ec29cb9d8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java
@@ -0,0 +1,50 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+package com.netscape.cms.servlet.csadmin.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="CertData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class InstallToken {
+    @XmlElement
+    private String token;
+
+    public InstallToken(String token) {
+        this.token = token;
+    }
+    
+    public InstallToken() {
+        // required by jaxb
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fab3016e679dd21a84e5aae232e9288fc338c6f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java
@@ -0,0 +1,101 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK --- 
+package com.netscape.cms.servlet.csadmin.model;
+
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="InstallTokenRequest")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class InstallTokenRequest {
+    @XmlElement
+    private String user;
+    
+    @XmlElement
+    private String password;
+    
+    @XmlElement
+    private String subsystem;
+    
+    @XmlElement
+    private String host;
+    
+    @XmlElement
+    private String port;
+
+    public InstallTokenRequest(String user, String password, String subsystem, String host, String port) {
+        super();
+        this.user = user;
+        this.password = password;
+        this.subsystem = subsystem;
+        this.host = host;
+        this.port = port;
+    }
+
+    public InstallTokenRequest() {
+        super();
+        // required for jaxb
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getSubsystem() {
+        return subsystem;
+    }
+
+    public void setSubsystem(String subsystem) {
+        this.subsystem = subsystem;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public String getPort() {
+        return port;
+    }
+
+    public void setPort(String port) {
+        this.port = port;
+    }
+    
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd12cfaf245c42832a507fc83ad1575f34fc19b4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java
@@ -0,0 +1,40 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="DomainInfo")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SecurityDomainHost {
+    protected String host;
+    protected String securePort;
+    protected String secureAgentPort;
+    protected String secureAdminPort;
+    protected String secureEEClientAuthPort;
+    protected String unSecurePort;
+    protected String clone;
+    protected String subsystemName;
+    protected String domainManager;
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java
new file mode 100644
index 0000000000000000000000000000000000000000..71922731e89e82ff803999f97b767f997e547cc4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java
@@ -0,0 +1,53 @@
+/**
+ * 
+ */
+package com.netscape.cms.servlet.csadmin.model;
+
+import java.util.Collection;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement
+public class SecurityDomainHostList {
+    protected Collection<SecurityDomainHost> systems;
+    
+    @XmlElement(name="SubsystemCount")
+    protected int count;
+
+    /**
+     * @return the systems
+     */
+    @XmlElementRef
+    public Collection<SecurityDomainHost> getSystems() {
+        return systems;
+    }
+
+    /**
+     * @param systems the systems to set
+     */
+    public void setSystems(Collection<SecurityDomainHost> systems) {
+        this.systems = systems;
+    }
+
+    /**
+     * @return the count
+     */
+    public int getCount() {
+        return count;
+    }
+
+    /**
+     * @param count the count to set
+     */
+    public void setCount(int count) {
+        this.count = count;
+    }
+    
+    
+}
diff --git a/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml b/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml
index b31bd751e0a7fff38641373628d98c41b3ed484f..e4ea799eb486e28b991a910ae57bda1e3510b27d 100644
--- a/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml
+++ b/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml
@@ -469,6 +469,28 @@
                          <param-value> ee          </param-value> </init-param>
    </servlet>
 
+   <context-param>
+      <param-name>resteasy.scan</param-name>
+      <param-value>true</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.servlet.mapping.prefix</param-name>
+      <param-value>/pki</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.resource.method-interceptors</param-name>
+      <param-value>
+         org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
+      </param-value>
+   </context-param>
+
+   <servlet>
+      <servlet-name>Resteasy</servlet-name>
+      <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+   </servlet>
+
 [PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
    <filter-mapping>
       <filter-name>  AgentRequestFilter  </filter-name>
@@ -493,6 +515,11 @@
 [PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
 
    <servlet-mapping>
+      <servlet-name>Resteasy</servlet-name>
+      <url-pattern>/pki/*</url-pattern>
+   </servlet-mapping>
+
+   <servlet-mapping>
       <servlet-name>  ocspacl  </servlet-name>
       <url-pattern>   /acl  </url-pattern>
    </servlet-mapping>
diff --git a/base/setup/pkicommon.pm b/base/setup/pkicommon.pm
index b96b9489c57998e2d76a92729d6a0c9b0bd5650a..b5ef8e140b06dfa80ebe65ad079087cfe739b48e 100755
--- a/base/setup/pkicommon.pm
+++ b/base/setup/pkicommon.pm
@@ -185,6 +185,7 @@ our $default_modutil_command       = undef;
 our $default_initscripts_path      = undef;
 our $default_registry_path         = undef;
 my  $resteasy_path                 = "/usr/share/java/resteasy";
+my  $httpcomponents_path           = "/usr/share/java/httpcomponents";
 
 our $default_dir_permissions       = 00770;
 our $default_exe_permissions       = 00770;
@@ -220,7 +221,7 @@ if ($^O eq "linux") {
         $default_java_path             = "/usr/share/java";
         $default_pki_java_path         = "/usr/share/java/pki";
         $default_system_jni_java_path  = "/usr/lib/java";
-        @default_jar_path = ($default_pki_java_path, $default_java_path, $default_system_jni_java_path, $resteasy_path);
+        @default_jar_path = ($default_pki_java_path, $default_java_path, $default_system_jni_java_path, $resteasy_path, $httpcomponents_path);
     } elsif ($default_hardware_platform eq "x86_64") {
         # 64-bit Linux
         $default_system_binaries       = "/bin";
@@ -232,7 +233,7 @@ if ($^O eq "linux") {
         $default_x86_64_jni_java_path  = "/usr/lib64/java";
         $default_system_jni_java_path  = "/usr/lib/java";
         @default_jar_path = ($default_pki_java_path, $default_java_path, $default_x86_64_jni_java_path,
-                             $default_system_jni_java_path, $resteasy_path);
+                             $default_system_jni_java_path, $resteasy_path, $httpcomponents_path);
     } else {
         emit("Unsupported '$^O' hardware platform '$default_hardware_platform'!", "error");
         exit 255;
diff --git a/base/setup/pkicreate b/base/setup/pkicreate
index 19f268a00db43109a46e80cd97a3f78a24caa257..b5453f2f6e3ecd31d64f621b6bfb2f532b881ca6 100755
--- a/base/setup/pkicreate
+++ b/base/setup/pkicreate
@@ -203,6 +203,7 @@ my $apache_commons_lang_jar_base_name     = "apache-commons-lang.jar";
 my $jakarta_commons_lang_jar_base_name    = "jakarta-commons-lang.jar";
 my $xml_commons_apis_jar_base_name        = "xml-commons-apis.jar";
 my $xml_commons_resolver_jar_base_name    = "xml-commons-resolver.jar";
+my $httpclient_jar_base_name              = "httpclient.jar";
 
 my $conf_base_name                = "conf";                   # CA, KRA, OCSP, TKS,
 my $catalina_properties_base_name = "catalina.properties";    # CA, KRA, OCSP, TKS
@@ -494,6 +495,8 @@ my $commons_lang_jar_file_path                   = undef;  # CA, KRA, OCSP, TKS
 my $commons_lang_jar_symlink_path                = undef;  # CA, KRA, OCSP, TKS
 my $commons_logging_jar_file_path                = undef;  # CA, KRA, OCSP, TKS
 my $commons_logging_jar_symlink_path             = undef;  # CA, KRA, OCSP, TKS
+my $httpclient_jar_file_path                     = undef;  # CA, KRA, OCSP, TKS
+my $httpclient_jar_symlink_path                  = undef;  # CA, KRA, OCSP, TKS
 my $jss_jar_file_path                            = undef;  # CA, KRA, OCSP, TKS
 my $jss_jar_symlink_path                         = undef;  # CA, KRA, OCSP, TKS
 my $ldapjdk_jar_file_path                        = undef;  # CA, KRA, OCSP, TKS
@@ -1890,6 +1893,11 @@ sub initialize_subdirectory_paths
             return 0;
         }
 
+        if (!defined($httpclient_jar_file_path = find_jar($httpclient_jar_base_name))) {
+            emit("could not find jar: $httpclient_jar_base_name", "error");
+            return 0;
+        }
+
         if (!defined($jettison_jar_file_path = find_jar($jettison_jar_base_name))) {
             emit("could not find jar: $jettison_jar_base_name", "error");
             return 0;
@@ -1963,7 +1971,8 @@ sub initialize_subdirectory_paths
                                                      . "/" . $resteasy_jettison_provider_jar_base_name;
         $jettison_jar_symlink_path                   = $webinf_lib_instance_path
                                                      . "/" . $jettison_jar_base_name;
-
+        $httpclient_jar_symlink_path                 = $webinf_lib_instance_path
+                                                     . "/" . $httpclient_jar_base_name;
 
         $webapps_root_instance_path        = $webapps_instance_path
                                            . "/"
@@ -3000,6 +3009,9 @@ sub process_pki_files_and_symlinks
         return 0 if !create_symlink($jettison_jar_symlink_path, $jettison_jar_file_path,
                                     $pki_user, $pki_group);
 
+        # create instance symlink to "httpclient.jar"
+        return 0 if !create_symlink($httpclient_jar_symlink_path, $httpclient_jar_file_path,
+                                    $pki_user, $pki_group);
 
     }
 
diff --git a/base/tks/shared/webapps/tks/WEB-INF/web.xml b/base/tks/shared/webapps/tks/WEB-INF/web.xml
index 28276fda05e987248f95e33de2c03116db41c341..c3f7593c2ddf316dfb7996ec3a7077a3430c9901 100644
--- a/base/tks/shared/webapps/tks/WEB-INF/web.xml
+++ b/base/tks/shared/webapps/tks/WEB-INF/web.xml
@@ -338,6 +338,28 @@
                          <param-value> ee          </param-value> </init-param>
    </servlet>
 
+   <context-param>
+      <param-name>resteasy.scan</param-name>
+      <param-value>true</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.servlet.mapping.prefix</param-name>
+      <param-value>/pki</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.resource.method-interceptors</param-name>
+      <param-value>
+         org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
+      </param-value>
+   </context-param>
+
+   <servlet>
+      <servlet-name>Resteasy</servlet-name>
+      <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+   </servlet>
+
 [PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
    <filter-mapping>
       <filter-name>  AgentRequestFilter  </filter-name>
@@ -361,6 +383,11 @@
 [PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
 
    <servlet-mapping>
+      <servlet-name>Resteasy</servlet-name>
+      <url-pattern>/pki/*</url-pattern>
+   </servlet-mapping>
+
+   <servlet-mapping>
       <servlet-name>  tksstart  </servlet-name>
       <url-pattern>   /start  </url-pattern>
    </servlet-mapping>
-- 
1.7.10

