From d3ee9e6bb0a1451c81099c7bfe2dafcc6be4c839 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Tue, 25 Feb 2014 17:03:31 -0800
Subject: [PATCH] For CA clones, always use their associated CA master to sign
 their 'sslserver' certificate during configuration.

* Dogtag TRAC Ticket #816 - pki-tomcat cannot be started after installation of
                            ipa replica with ca
---
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 55 ++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 30d908f..7698e00 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -2217,8 +2217,32 @@ public class ConfigurationUtils {
         CMS.debug("configCert: caType is " + caType);
         X509CertImpl cert = null;
         String certTag = certObj.getCertTag();
+        String caTypeHolder = null;
 
         try {
+            String selection = config.getString("preop.subsystem.select");
+            if (selection.equals("clone")) {
+                String csType = config.getString("cs.type");
+                if (csType.equals("CA") && certTag.equals("sslserver")) {
+                    // retrieve and store original CS.cfg entries
+                    caTypeHolder = config.getString("preop.ca.type", "");
+
+                    // add/modify CS.cfg entries
+                    config.putString("preop.ca.type", "master_ca");
+                    config.putString("preop.cert.signing.type", "remote");
+                    config.putString("preop.cert.signing.profile","caInstallCACert");
+                    config.putString("preop.cert.sslserver.type", "remote");
+                    config.putString("preop.cert.sslserver.profile","caInternalAuthServerCert");
+
+                    // modify certObj 'mType'
+                    certObj.setType("remote");
+
+                    // certObj:  fetch revised 'mType'
+                    caType = certObj.getType();
+                    CMS.debug("configCert: caType is " + caType + " (revised)");
+                }
+            }
+
             updateConfig(config, certTag);
             if (caType.equals("remote")) {
                 String v = config.getString("preop.ca.type", "");
@@ -2278,6 +2302,37 @@ public class ConfigurationUtils {
                     if (cert == null) {
                         throw new IOException("Error: remote certificate is null");
                     }
+                } else if (v.equals("master_ca")) {
+                    // Only used for signing the 'sslserver' certificate of a
+                    // cloned CA.  Although generally the security domain CA
+                    // and the master CA will be the same, in this case
+                    // we want to be certain that this particular certificate
+                    // is always signed by the cloned CA's master CA to avoid
+                    // any changes which may have been made to the X500Name
+                    // directory string encoding order.
+                    String ca_hostname = "";
+                    int ca_port = -1;
+                    try {
+                        ca_hostname = config.getString("preop.master.hostname", "");
+                        ca_port = config.getInteger("preop.master.httpsport", -1);
+                    } catch (Exception ee) {
+                    }
+
+                    CMS.debug("NamePanel: For this Cloned CA, always use its Master CA to generate the 'sslserver' certificate to avoid any changes which may have been made to the X500Name directory string encoding order.");
+
+                    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");
+                    }
+
+                    // restore original CS.cfg entries
+                    config.putString("preop.ca.type", caTypeHolder);
                 } else if (v.equals("otherca")) {
                     config.putString(subsystem + "." + certTag + ".cert",
                             "...paste certificate here...");
-- 
1.8.4.2

