>From f0eaad1327aebc01a1d15a4d5a2c7873e6cb9ed3 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 25 Mar 2016 03:12:27 +0100
Subject: [PATCH] Simplified deployment properties for existing CA case.

A new pki_existing deployment property has been added to install
CA with existing CA certificate and key in a single step.

New certificate deployment properties have been added as aliases
for some external CA properties to allow them to be used in more
general cases:
- pki_ca_signing_csr_path  -> pki_external_csr_path
- pki_ca_signing_cert_path -> pki_external_ca_cert_path
- pki_cert_chain_path      -> pki_external_ca_cert_chain_path
- pki_cert_chain_nickname  -> pki_external_ca_cert_chain_nickname

https://fedorahosted.org/pki/ticket/1736
---
 base/server/etc/default.cfg                        | 13 +++++---
 .../python/pki/server/deployment/pkihelper.py      |  7 +++-
 .../server/deployment/scriptlets/configuration.py  | 38 +++++++++++++++++-----
 3 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
index 924df9ddcd0001209c8552d1fba813980222c1b3..dc30468df7808b9962d2ad82f94f88be4c6be897 100644
--- a/base/server/etc/default.cfg
+++ b/base/server/etc/default.cfg
@@ -135,6 +135,9 @@ pki_theme_server_dir=/usr/share/pki/common-ui
 pki_token_name=internal
 pki_token_password=
 pki_user=pkiuser
+pki_existing=False
+pki_cert_chain_path=
+pki_cert_chain_nickname=caSigningCert External CA
 pki_pkcs12_path=
 pki_pkcs12_password=
 
@@ -370,17 +373,19 @@ pki_ca_signing_nickname=caSigningCert cert-%(pki_instance_name)s CA
 pki_ca_signing_signing_algorithm=SHA256withRSA
 pki_ca_signing_subject_dn=cn=CA Signing Certificate,o=%(pki_security_domain_name)s
 pki_ca_signing_token=Internal Key Storage Token
+pki_ca_signing_csr_path=
+pki_ca_signing_cert_path=
 pki_external=False
 pki_req_ext_add=False
 # MS subca request ext data
 pki_req_ext_oid=1.3.6.1.4.1.311.20.2
 pki_req_ext_critical=False
 pki_req_ext_data=1E0A00530075006200430041
-pki_external_csr_path=
 pki_external_step_two=False
-pki_external_ca_cert_chain_path=
-pki_external_ca_cert_chain_nickname=caSigningCert External CA
-pki_external_ca_cert_path=
+pki_external_csr_path=%(pki_ca_signing_csr_path)s
+pki_external_ca_cert_path=%(pki_ca_signing_cert_path)s
+pki_external_ca_cert_chain_path=%(pki_cert_chain_path)s
+pki_external_ca_cert_chain_nickname=%(pki_cert_chain_nickname)s
 pki_external_pkcs12_path=%(pki_pkcs12_path)s
 pki_external_pkcs12_password=%(pki_pkcs12_password)s
 pki_import_admin_cert=False
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index cd4e3e26f72ad175aa13fd87d1c8344c6d9248f4..f01f6f69ff66d3687875c8f3d88840daf2115e3f 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -501,6 +501,7 @@ class ConfigurationFile:
         self.add_req_ext = config.str2bool(
             self.mdict['pki_req_ext_add'])
 
+        self.existing = config.str2bool(self.mdict['pki_existing'])
         self.external = config.str2bool(self.mdict['pki_external'])
         self.external_step_one = not config.str2bool(self.mdict['pki_external_step_two'])
         self.external_step_two = not self.external_step_one
@@ -3786,9 +3787,12 @@ class ConfigClient:
         self.mdict = deployer.mdict
         # set useful 'boolean' object variables for this class
         self.clone = config.str2bool(self.mdict['pki_clone'])
+
+        self.existing = config.str2bool(self.mdict['pki_existing'])
         self.external = config.str2bool(self.mdict['pki_external'])
         self.external_step_two = config.str2bool(
             self.mdict['pki_external_step_two'])
+
         self.standalone = config.str2bool(self.mdict['pki_standalone'])
         self.subordinate = config.str2bool(self.mdict['pki_subordinate'])
         # set useful 'string' object variables for this class
@@ -3999,7 +4003,8 @@ class ConfigClient:
             data.tokenPassword = self.mdict['pki_token_password']
         data.subsystemName = self.mdict['pki_subsystem_name']
 
-        data.external = self.external
+        # Process existing CA installation like external CA
+        data.external = self.external or self.existing
         data.standAlone = self.standalone
 
         if self.standalone:
diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py
index b5d743894d2dcedbad38f7edf109915100c3b0f3..cc8c7f9b68f9a943da4d640843224cc5533fba5d 100644
--- a/base/server/python/pki/server/deployment/scriptlets/configuration.py
+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py
@@ -93,13 +93,15 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         token = deployer.mdict['pki_token_name']
         nssdb = instance.open_nssdb(token)
 
+        existing = deployer.configuration_file.existing
         external = deployer.configuration_file.external
         step_one = deployer.configuration_file.external_step_one
         step_two = deployer.configuration_file.external_step_two
 
         try:
-            if external and step_one:  # external/existing CA step 1
+            if external and step_one:  # external CA step 1 only
 
+                # Determine CA signing key type and algorithm
                 key_type = deployer.mdict['pki_ca_signing_key_type']
                 key_alg = deployer.mdict['pki_ca_signing_key_algorithm']
 
@@ -129,6 +131,10 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 # import it into CS.cfg.
                 external_csr_path = deployer.mdict['pki_external_csr_path']
                 if external_csr_path:
+                    config.pki_log.info(
+                        "generating CA signing certificate request in %s",
+                        external_csr_path,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
                     nssdb.create_request(
                         subject_dn=deployer.mdict['pki_ca_signing_subject_dn'],
                         request_file=external_csr_path,
@@ -136,8 +142,10 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                         key_size=key_size,
                         curve=curve,
                         hash_alg=hash_alg)
+
                     with open(external_csr_path) as f:
                         signing_csr = f.read()
+
                     signing_csr = pki.nssdb.convert_csr(signing_csr, 'pem', 'base64')
                     subsystem.config['ca.signing.certreq'] = signing_csr
 
@@ -147,20 +155,27 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
 
                 subsystem.save()
 
-            elif external and step_two:  # external/existing CA step 2
+            if existing or external and step_two:  # existing CA or external CA step 2
 
-                # If specified, import existing CA cert request into CS.cfg.
-                external_csr_path = deployer.mdict['pki_external_csr_path']
-                if external_csr_path:
-                    with open(external_csr_path) as f:
+                # If specified, import CA signing CSR into CS.cfg.
+                signing_csr_path = deployer.mdict['pki_external_csr_path']
+                if signing_csr_path:
+                    config.pki_log.info(
+                        "importing CA signing CSR from %s",
+                        signing_csr_path,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    with open(signing_csr_path) as f:
                         signing_csr = f.read()
                     signing_csr = pki.nssdb.convert_csr(signing_csr, 'pem', 'base64')
                     subsystem.config['ca.signing.certreq'] = signing_csr
 
-                # If specified, import externally-signed CA cert into NSS database.
+                # If specified, import CA signing cert into NSS database.
                 signing_nickname = deployer.mdict['pki_ca_signing_nickname']
                 signing_cert_file = deployer.mdict['pki_external_ca_cert_path']
                 if signing_cert_file:
+                    config.pki_log.info(
+                        "importing %s from %s", signing_nickname, signing_cert_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
                     nssdb.add_cert(
                         nickname=signing_nickname,
                         cert_file=signing_cert_file,
@@ -169,6 +184,9 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 # If specified, import certs and keys from PKCS #12 file into NSS database.
                 pkcs12_file = deployer.mdict['pki_external_pkcs12_path']
                 if pkcs12_file:
+                    config.pki_log.info(
+                        "importing certificates and keys from %s", pkcs12_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
                     pkcs12_password = deployer.mdict['pki_external_pkcs12_password']
                     nssdb.import_pkcs12(pkcs12_file, pkcs12_password)
 
@@ -179,13 +197,17 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                     deployer.mdict['pki_external_ca_cert_chain_nickname']
                 external_ca_cert_chain_file = deployer.mdict['pki_external_ca_cert_chain_path']
                 if external_ca_cert_chain_file:
+                    config.pki_log.info(
+                        "importing certificate chain %s from %s",
+                        external_ca_cert_chain_nickname, external_ca_cert_chain_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
                     cert_chain, _nicks = nssdb.import_cert_chain(
                         nickname=external_ca_cert_chain_nickname,
                         cert_chain_file=external_ca_cert_chain_file,
                         trust_attributes='CT,C,C')
                     subsystem.config['ca.external_ca_chain.cert'] = cert_chain
 
-                # Export CA cert from NSS database and import it into CS.cfg.
+                # Export CA signing cert from NSS database and import it into CS.cfg.
                 signing_cert_data = nssdb.get_cert(
                     nickname=signing_nickname,
                     output_format='base64')
-- 
2.5.5

