Attached is a preliminary patch to provide a mechanism to import all existing CA system certificates into a new CA instance. It's not ready to be checked in yet. It's posted for evaluation only.

Here's the doc:

http://pki.fedoraproject.org/wiki/Installing_CA_with_Existing_System_Certificates

The patch has only been tested with PKCS #12 installation. It has not been tested with HSM. Also currently it breaks the external CA case. Nevertheless, I think it's pretty close to complete, but it will need more thorough testing.

--
Endi S. Dewata
>From 2e277b2786fde5d31ea805a9b25d4222cf78b54c Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <[email protected]>
Date: Thu, 14 Apr 2016 19:51:52 +0200
Subject: [PATCH] Migrating system certificates.

https://fedorahosted.org/pki/ticket/2280
---
 .../cms/servlet/csadmin/ConfigurationUtils.java    |  28 +---
 .../dogtagpki/server/rest/SystemConfigService.java |  30 +++-
 base/server/etc/default.cfg                        |   8 +
 .../server/deployment/scriptlets/configuration.py  | 175 +++++++++++++++++++++
 4 files changed, 213 insertions(+), 28 deletions(-)

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 2da4e48658354116eb8ef1427133bc928226bd0f..9160958a42986ac26b95396dcb070ef61a98ec60 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
@@ -187,7 +187,7 @@ import netscape.security.x509.X509Key;
  */
 public class ConfigurationUtils {
 
-    private static final String PCERT_PREFIX = "preop.cert.";
+    public static final String PCERT_PREFIX = "preop.cert.";
     public static String SUCCESS = "0";
     public static String FAILURE = "1";
     public static String AUTH_FAILURE = "2";
@@ -3047,29 +3047,11 @@ public class ConfigurationUtils {
         return pubk;
     }
 
-    public static void loadCert(IConfigStore config, Cert cert) throws Exception {
+    public static void loadCert(IConfigStore config, X509Certificate x509Cert) throws Exception {
 
-        String tag = cert.getCertTag();
-        CMS.debug("ConfigurationUtils: loadCert(" + tag + ")");
-
-        CryptoManager cm = CryptoManager.getInstance();
-        X509Certificate x509Cert = cm.findCertByNickname(cert.getNickname());
-
-        if (!x509Cert.getSubjectDN().equals(x509Cert.getIssuerDN())) {
-            CMS.debug("ConfigurationUtils: " + tag + " cert is not self-signed");
-
-            String subsystem = config.getString(PCERT_PREFIX + tag + ".subsystem");
-            String certChain = config.getString(subsystem + ".external_ca_chain.cert");
-            cert.setCertChain(certChain);
-
-            return;
-        }
-
-        CMS.debug("ConfigurationUtils: " + tag + " cert is self-signed");
-
-        // When importing existing self-signed CA certificate, create a
-        // certificate record to reserve the serial number. Otherwise it
-        // might conflict with system certificates to be created later.
+        // When importing existing certificate, create a certificate record
+        // to reserve the serial number. Otherwise it might conflict with
+        // system certificates to be created later.
 
         X509CertImpl x509CertImpl = new X509CertImpl(x509Cert.getEncoded());
 
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
index 6fc37b5eec90547c25c420d0172953b91134d352..33ad3dd04dffa3b67aedc5ebd920069f884bd5b7 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
@@ -447,7 +447,17 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         }
         cs.commit(false);
 
-        if (request.isExternal() && tag.equals("signing")) { // external/existing CA
+        boolean certAlreadyExists;
+        X509Certificate x509Cert = null;
+        try {
+            CryptoManager cm = CryptoManager.getInstance();
+            x509Cert = cm.findCertByNickname(certData.getNickname());
+            certAlreadyExists = true;
+        } catch (ObjectNotFoundException e) {
+            certAlreadyExists = false;
+        }
+
+        if (request.isExternal() && certAlreadyExists) { // external/existing cert
             // load key pair for existing and externally-signed signing cert
             CMS.debug("SystemConfigService: loading signing cert key pair");
             KeyPair pair = ConfigurationUtils.loadKeyPair(certData.getNickname(), certData.getToken());
@@ -476,7 +486,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         cert.setSubsystem(cs.getString("preop.cert." + tag + ".subsystem"));
         cert.setType(cs.getString("preop.cert." + tag + ".type"));
 
-        if (request.isExternal() && tag.equals("signing")) { // external/existing CA
+        if (request.isExternal() && certAlreadyExists) { // external/existing cert
 
             // update configuration for existing or externally-signed signing certificate
             String certStr = cs.getString("ca." + tag + ".cert" );
@@ -506,13 +516,23 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
             CMS.debug("Step 2:  certStr for '" + tag + "' is " + certStr);
         }
 
-        if (request.isExternal() && tag.equals("signing")) { // external/existing CA
+        if (request.isExternal() && certAlreadyExists) { // external/existing cert
 
             CMS.debug("SystemConfigService: Loading cert request for " + tag + " cert");
             ConfigurationUtils.loadCertRequest(cs, tag, cert);
 
-            CMS.debug("SystemConfigService: Loading cert " + tag);
-            ConfigurationUtils.loadCert(cs, cert);
+            // if CA signing cert is externally signed, load the cert chain
+            if (tag.equals("signing") && !x509Cert.getSubjectDN().equals(x509Cert.getIssuerDN())) {
+                CMS.debug("ConfigurationUtils: Loading cert chain for externally-signed CA signing cert");
+
+                String subsystem = cs.getString(ConfigurationUtils.PCERT_PREFIX + tag + ".subsystem");
+                String certChain = cs.getString(subsystem + ".external_ca_chain.cert");
+                cert.setCertChain(certChain);
+
+            } else {
+                CMS.debug("SystemConfigService: Loading external cert " + tag);
+                ConfigurationUtils.loadCert(cs, x509Cert);
+            }
 
         } else if (request.getStandAlone()) {
             // Handle Cert Requests for everything EXCEPT Stand-alone PKI (Step 2)
diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
index 2cb887d09f9dfef7484df6aa796147bc2691f2ed..c79d14af4f1159fec51d31944ee63c5b07d210cb 100644
--- a/base/server/etc/default.cfg
+++ b/base/server/etc/default.cfg
@@ -124,12 +124,16 @@ pki_ssl_server_key_type=rsa
 pki_ssl_server_nickname=Server-Cert cert-%(pki_instance_name)s
 pki_ssl_server_subject_dn=cn=%(pki_hostname)s,o=%(pki_security_domain_name)s
 pki_ssl_server_token=Internal Key Storage Token
+pki_ssl_server_csr_path=
+pki_ssl_server_cert_path=
 pki_subsystem_key_algorithm=SHA256withRSA
 pki_subsystem_key_size=2048
 pki_subsystem_key_type=rsa
 pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s
 pki_subsystem_subject_dn=cn=Subsystem Certificate,o=%(pki_security_domain_name)s
 pki_subsystem_token=Internal Key Storage Token
+pki_subsystem_csr_path=
+pki_subsystem_cert_path=
 pki_theme_enable=True
 pki_theme_server_dir=/usr/share/pki/common-ui
 pki_token_name=internal
@@ -397,6 +401,8 @@ pki_ocsp_signing_nickname=ocspSigningCert cert-%(pki_instance_name)s CA
 pki_ocsp_signing_signing_algorithm=SHA256withRSA
 pki_ocsp_signing_subject_dn=cn=CA OCSP Signing Certificate,o=%(pki_security_domain_name)s
 pki_ocsp_signing_token=Internal Key Storage Token
+pki_ocsp_signing_csr_path=
+pki_ocsp_signing_cert_path=
 pki_profiles_in_ldap=False
 pki_random_serial_numbers_enable=False
 pki_subordinate=False
@@ -409,6 +415,8 @@ pki_admin_subject_dn=cn=PKI Administrator,e=%(pki_admin_email)s,o=%(pki_security
 pki_admin_uid=caadmin
 pki_audit_signing_nickname=auditSigningCert cert-%(pki_instance_name)s CA
 pki_audit_signing_subject_dn=cn=CA Audit Signing Certificate,o=%(pki_security_domain_name)s
+pki_audit_signing_csr_path=
+pki_audit_signing_cert_path=
 pki_ds_base_dn=o=%(pki_instance_name)s-CA
 pki_ds_database=%(pki_instance_name)s-CA
 pki_ds_hostname=%(pki_hostname)s
diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py
index b8505dd9b7d59a527f21c07f2fb55bde1f46eafa..b0dd77773823f3eb26a2c7f517065f2354f00f18 100644
--- a/base/server/python/pki/server/deployment/scriptlets/configuration.py
+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py
@@ -210,6 +210,56 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                         signing_csr, 'pem', 'base64')
                     subsystem.config['ca.signing.certreq'] = signing_csr
 
+                # If specified, import CA OCSP signing CSR into CS.cfg.
+                ocsp_signing_csr_path = \
+                    deployer.mdict['pki_ocsp_signing_csr_path']
+                if ocsp_signing_csr_path:
+                    config.pki_log.info(
+                        "importing CA OCSP signing certificate request from %s",
+                        ocsp_signing_csr_path,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    with open(ocsp_signing_csr_path) as f:
+                        ocsp_signing_csr = f.read()
+                    ocsp_signing_csr = pki.nssdb.convert_csr(ocsp_signing_csr, 'pem', 'base64')
+                    subsystem.config['ca.ocsp_signing.certreq'] = ocsp_signing_csr
+
+                # If specified, import CA audit signing CSR into CS.cfg.
+                audit_signing_csr_path = \
+                    deployer.mdict['pki_audit_signing_csr_path']
+                if audit_signing_csr_path:
+                    config.pki_log.info(
+                        "importing CA audit signing certificate request from %s",
+                        audit_signing_csr_path,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    with open(audit_signing_csr_path) as f:
+                        audit_signing_csr = f.read()
+                    audit_signing_csr = pki.nssdb.convert_csr(audit_signing_csr, 'pem', 'base64')
+                    subsystem.config['ca.audit_signing.certreq'] = audit_signing_csr
+
+                # If specified, import subsystem CSR into CS.cfg.
+                subsystem_csr_path = deployer.mdict['pki_subsystem_csr_path']
+                if subsystem_csr_path:
+                    config.pki_log.info(
+                        "importing subsystem certificate request from %s",
+                        subsystem_csr_path,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    with open(subsystem_csr_path) as f:
+                        subsystem_csr = f.read()
+                    subsystem_csr = pki.nssdb.convert_csr(subsystem_csr, 'pem', 'base64')
+                    subsystem.config['ca.subsystem.certreq'] = subsystem_csr
+
+                # If specified, import SSL server CSR into CS.cfg.
+                sslserver_csr_path = deployer.mdict['pki_ssl_server_csr_path']
+                if sslserver_csr_path:
+                    config.pki_log.info(
+                        "importing SSL server certificate request from %s",
+                        sslserver_csr_path,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    with open(sslserver_csr_path) as f:
+                        sslserver_csr = f.read()
+                    sslserver_csr = pki.nssdb.convert_csr(sslserver_csr, 'pem', 'base64')
+                    subsystem.config['ca.sslserver.certreq'] = sslserver_csr
+
                 # 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']
@@ -223,6 +273,58 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                         cert_file=signing_cert_file,
                         trust_attributes='CT,C,C')
 
+                # If specified, import OCSP signing cert into NSS database.
+                ocsp_signing_nickname = deployer.mdict['pki_ocsp_signing_nickname']
+                ocsp_signing_cert_file = deployer.mdict['pki_ocsp_signing_cert_path']
+                if ocsp_signing_cert_file:
+                    config.pki_log.info(
+                        "importing %s from %s",
+                        ocsp_signing_nickname, ocsp_signing_cert_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    nssdb.add_cert(
+                        nickname=ocsp_signing_nickname,
+                        cert_file=ocsp_signing_cert_file,
+                        trust_attributes=',,')
+
+                # If specified, import audit signing cert into NSS database.
+                audit_signing_nickname = deployer.mdict['pki_audit_signing_nickname']
+                audit_signing_cert_file = deployer.mdict['pki_audit_signing_cert_path']
+                if audit_signing_cert_file:
+                    config.pki_log.info(
+                        "importing %s from %s",
+                        audit_signing_nickname, audit_signing_cert_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    nssdb.add_cert(
+                        nickname=audit_signing_nickname,
+                        cert_file=audit_signing_cert_file,
+                        trust_attributes=',,P')
+
+                # If specified, import subsystem cert into NSS database.
+                subsystem_nickname = deployer.mdict['pki_subsystem_nickname']
+                subsystem_cert_file = deployer.mdict['pki_subsystem_cert_path']
+                if subsystem_cert_file:
+                    config.pki_log.info(
+                        "importing %s from %s",
+                        subsystem_nickname, subsystem_cert_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    nssdb.add_cert(
+                        nickname=subsystem_nickname,
+                        cert_file=subsystem_cert_file,
+                        trust_attributes=',,')
+
+                # If specified, import SSL server cert into NSS database.
+                sslserver_nickname = deployer.mdict['pki_ssl_server_nickname']
+                sslserver_cert_file = deployer.mdict['pki_ssl_server_cert_path']
+                if sslserver_cert_file:
+                    config.pki_log.info(
+                        "importing %s from %s",
+                        sslserver_nickname, sslserver_cert_file,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    nssdb.add_cert(
+                        nickname=sslserver_nickname,
+                        cert_file=sslserver_cert_file,
+                        trust_attributes=',,')
+
                 # If specified, import certs and keys from PKCS #12 file
                 # into NSS database.
                 pkcs12_file = deployer.mdict['pki_external_pkcs12_path']
@@ -267,6 +369,79 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 subsystem.config['ca.signing.defaultSigningAlgorithm'] = (
                     deployer.mdict['pki_ca_signing_signing_algorithm'])
 
+                # Export CA OCSP signing cert from NSS database and import it into CS.cfg.
+                ocsp_signing_nickname = deployer.mdict['pki_ocsp_signing_nickname']
+                try:
+                    ocsp_signing_cert_data = nssdb.get_cert(
+                        nickname=ocsp_signing_nickname,
+                        output_format='base64')
+                    subsystem.config['ca.ocsp_signing.nickname'] = ocsp_signing_nickname
+                    subsystem.config['ca.ocsp_signing.tokenname'] = \
+                        deployer.mdict['pki_ocsp_signing_token']
+                    subsystem.config['ca.ocsp_signing.cert'] = ocsp_signing_cert_data
+                    subsystem.config['ca.ocsp_signing.cacertnickname'] = ocsp_signing_nickname
+                    subsystem.config['ca.ocsp_signing.certnickname'] = ocsp_signing_nickname
+                    subsystem.config['ca.ocsp_signing.newNickname'] = ocsp_signing_nickname
+                    subsystem.config['ca.ocsp_signing.defaultSigningAlgorithm'] = \
+                        deployer.mdict['pki_ocsp_signing_signing_algorithm']
+                except Exception, e:
+                    config.pki_log.info(
+                        "unable to export certificate %s: %s",
+                        ocsp_signing_nickname, e,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    # TODO: ignore only if the cert does not exist
+
+                # Export CA audit signing cert from NSS database and import it into CS.cfg.
+                audit_signing_nickname = deployer.mdict['pki_audit_signing_nickname']
+                try:
+                    audit_signing_cert_data = nssdb.get_cert(
+                        nickname=audit_signing_nickname,
+                        output_format='base64')
+                    subsystem.config['ca.audit_signing.nickname'] = audit_signing_nickname
+                    subsystem.config['ca.audit_signing.tokenname'] = \
+                        deployer.mdict['pki_audit_signing_token']
+                    subsystem.config['ca.audit_signing.cert'] = audit_signing_cert_data
+                except Exception, e:
+                    config.pki_log.info(
+                        "unable to export certificate %s: %s",
+                        audit_signing_nickname, e,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    # TODO: ignore only if the cert does not exist
+
+                # Export subsystem cert from NSS database and import it into CS.cfg.
+                subsystem_nickname = deployer.mdict['pki_subsystem_nickname']
+                try:
+                    subsystem_cert_data = nssdb.get_cert(
+                        nickname=subsystem_nickname,
+                        output_format='base64')
+                    subsystem.config['ca.subsystem.nickname'] = subsystem_nickname
+                    subsystem.config['ca.subsystem.tokenname'] = deployer.mdict['pki_subsystem_token']
+                    subsystem.config['ca.subsystem.cert'] = subsystem_cert_data
+                    subsystem.config['ca.subsystem.cacertnickname'] = subsystem_nickname
+                except Exception, e:
+                    config.pki_log.info(
+                        "unable to export certificate %s: %s",
+                        subsystem_nickname, e,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    # TODO: ignore only if the cert does not exist
+
+                # Export SSL server cert from NSS database and import it into CS.cfg.
+                sslserver_nickname = deployer.mdict['pki_ssl_server_nickname']
+                try:
+                    sslserver_cert_data = nssdb.get_cert(
+                        nickname=sslserver_nickname,
+                        output_format='base64')
+                    subsystem.config['ca.sslserver.nickname'] = sslserver_nickname
+                    subsystem.config['ca.sslserver.tokenname'] = deployer.mdict['pki_ssl_server_token']
+                    subsystem.config['ca.sslserver.cert'] = sslserver_cert_data
+                    subsystem.config['ca.sslserver.cacertnickname'] = sslserver_nickname
+                except Exception, e:
+                    config.pki_log.info(
+                        "unable to export certificate %s: %s",
+                        sslserver_nickname, e,
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    # TODO: ignore only if the cert does not exist
+
                 subsystem.save()
 
                 # verify the signing certificate
-- 
2.5.5

_______________________________________________
Pki-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/pki-devel

Reply via email to