ac7d03
From 1b17dfa9fb62215eeb1ceadc7902785a7ed384e9 Mon Sep 17 00:00:00 2001
ac7d03
From: Jan Cholasta <jcholast@redhat.com>
ac7d03
Date: Tue, 28 Feb 2017 10:58:28 +0000
ac7d03
Subject: [PATCH] cainstance: use correct profile for lightweight CA
ac7d03
 certificates
ac7d03
ac7d03
Use Dogtag's `caCACert` CA certificate profile rather than the
ac7d03
`ipaCACertRenewal` virtual profile for lightweight CA certificates.
ac7d03
ac7d03
The `ipaCACertRenewal` virtual profile adds special handling of externally
ac7d03
signed CA certificates and LDAP replication of issued certificates on top
ac7d03
of `caCACert`, neither of which is relevant for lightweight CA
ac7d03
certificates.
ac7d03
ac7d03
Remove all of the special casing of lightweight CA certificates from
ac7d03
dogtag-ipa-ca-renew-agent-submit.
ac7d03
ac7d03
Make sure existing lightweight CA certmonger tracking requests are updated
ac7d03
on server upgrade.
ac7d03
ac7d03
https://pagure.io/freeipa/issue/5799
ac7d03
ac7d03
Reviewed-By: David Kupka <dkupka@redhat.com>
ac7d03
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
ac7d03
---
ac7d03
 .../certmonger/dogtag-ipa-ca-renew-agent-submit    | 36 +++-------------------
ac7d03
 ipaserver/install/cainstance.py                    |  7 ++---
ac7d03
 ipaserver/install/server/upgrade.py                | 16 ++++++++++
ac7d03
 3 files changed, 23 insertions(+), 36 deletions(-)
ac7d03
ac7d03
diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
ac7d03
index f253fd9587ac1ef3ece712ca9999c1ea4f3d55d8..51b0880c5b57758845e2ffa0c9545bbca7e8c751 100755
ac7d03
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
ac7d03
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
ac7d03
@@ -98,25 +98,7 @@ def get_nickname():
ac7d03
         DN('CN=IPA RA', subject_base): 'ipaCert',
ac7d03
     }
ac7d03
 
ac7d03
-    try:
ac7d03
-        return nickname_by_subject_dn[DN(subject)]
ac7d03
-    except KeyError:
ac7d03
-        cas = api.Command.ca_find(ipacasubjectdn=DN(subject))['result']
ac7d03
-        if len(cas) == 0:
ac7d03
-            return None
ac7d03
-        return 'caSigningCert cert-pki-ca {}'.format(cas[0]['ipacaid'][0])
ac7d03
-
ac7d03
-
ac7d03
-def is_lightweight_ca():
ac7d03
-    nickname = get_nickname() or ''
ac7d03
-    return nickname != IPA_CA_NICKNAME and nickname.startswith(IPA_CA_NICKNAME)
ac7d03
-
ac7d03
-def is_renewable():
ac7d03
-    cert = os.environ.get('CERTMONGER_CERTIFICATE')
ac7d03
-    if not cert:
ac7d03
-        return False
ac7d03
-    else:
ac7d03
-        return x509.is_self_signed(cert) or is_lightweight_ca()
ac7d03
+    return nickname_by_subject_dn.get(DN(subject))
ac7d03
 
ac7d03
 
ac7d03
 def is_replicated():
ac7d03
@@ -276,11 +258,6 @@ def store_cert():
ac7d03
     if not cert:
ac7d03
         return (REJECTED, "New certificate requests not supported")
ac7d03
 
ac7d03
-    if is_lightweight_ca():
ac7d03
-        # Lightweight CAs are updated in Dogtag's NSSDB
ac7d03
-        # by Dogtag itself, so do not store it
ac7d03
-        return (ISSUED, cert)
ac7d03
-
ac7d03
     dercert = x509.normalize_certificate(cert)
ac7d03
 
ac7d03
     dn = DN(('cn', nickname), ('cn', 'ca_renewal'),
ac7d03
@@ -405,12 +382,6 @@ def retrieve_cert_continuous():
ac7d03
     if old_cert:
ac7d03
         old_cert = x509.normalize_certificate(old_cert)
ac7d03
 
ac7d03
-    if is_lightweight_ca():
ac7d03
-        # Lightweight CAs are updated in Dogtag's NSSDB
ac7d03
-        # by Dogtag itself, so do not try to retrieve it.
ac7d03
-        # Everything is fine as is.
ac7d03
-        return (ISSUED, os.environ.get('CERTMONGER_CERTIFICATE'))
ac7d03
-
ac7d03
     result = call_handler(retrieve_or_reuse_cert)
ac7d03
     if result[0] != ISSUED:
ac7d03
         return result
ac7d03
@@ -466,12 +437,13 @@ def renew_ca_cert():
ac7d03
     cert = os.environ.get('CERTMONGER_CERTIFICATE')
ac7d03
     if not cert:
ac7d03
         return (REJECTED, "New certificate requests not supported")
ac7d03
+    is_self_signed = x509.is_self_signed(cert)
ac7d03
 
ac7d03
     operation = os.environ.get('CERTMONGER_OPERATION')
ac7d03
     if operation == 'SUBMIT':
ac7d03
         state = 'retrieve'
ac7d03
 
ac7d03
-        if is_renewable() and is_renewal_master():
ac7d03
+        if is_self_signed and is_renewal_master():
ac7d03
             state = 'request'
ac7d03
     elif operation == 'POLL':
ac7d03
         cookie = os.environ.get('CERTMONGER_CA_COOKIE')
ac7d03
@@ -489,7 +461,7 @@ def renew_ca_cert():
ac7d03
 
ac7d03
     if state == 'retrieve':
ac7d03
         result = call_handler(retrieve_cert)
ac7d03
-        if result[0] == REJECTED and not is_renewable():
ac7d03
+        if result[0] == REJECTED and not is_self_signed:
ac7d03
             syslog.syslog(syslog.LOG_ALERT,
ac7d03
                           "Certificate with subject '%s' is about to expire, "
ac7d03
                           "use ipa-cacert-manage to renew it"
ac7d03
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
ac7d03
index 97baa606c960806376e025b5654eea816da207ed..546e1b7b39b323bbaeae3fb57d31ea4152d5e418 100644
ac7d03
--- a/ipaserver/install/cainstance.py
ac7d03
+++ b/ipaserver/install/cainstance.py
ac7d03
@@ -436,7 +436,7 @@ class CAInstance(DogtagInstance):
ac7d03
                     self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry)
ac7d03
 
ac7d03
                 self.step("configuring certmonger renewal for lightweight CAs",
ac7d03
-                          self.__add_lightweight_ca_tracking_requests)
ac7d03
+                          self.add_lightweight_ca_tracking_requests)
ac7d03
 
ac7d03
         if ra_only:
ac7d03
             runtime = None
ac7d03
@@ -1246,7 +1246,7 @@ class CAInstance(DogtagInstance):
ac7d03
         os.chmod(keyfile, 0o600)
ac7d03
         os.chown(keyfile, pent.pw_uid, pent.pw_gid)
ac7d03
 
ac7d03
-    def __add_lightweight_ca_tracking_requests(self):
ac7d03
+    def add_lightweight_ca_tracking_requests(self):
ac7d03
         try:
ac7d03
             lwcas = api.Backend.ldap2.get_entries(
ac7d03
                 base_dn=api.env.basedn,
ac7d03
@@ -1810,11 +1810,10 @@ def add_lightweight_ca_tracking_requests(logger, lwcas):
ac7d03
                     pin=certmonger.get_pin('internal'),
ac7d03
                     nickname=nickname,
ac7d03
                     ca=ipalib.constants.RENEWAL_CA_NAME,
ac7d03
+                    profile='caCACert',
ac7d03
                     pre_command='stop_pkicad',
ac7d03
                     post_command='renew_ca_cert "%s"' % nickname,
ac7d03
                 )
ac7d03
-                request_id = certmonger.get_request_id(criteria)
ac7d03
-                certmonger.modify(request_id, profile='ipaCACertRenewal')
ac7d03
                 logger.debug(
ac7d03
                     'Lightweight CA renewal: '
ac7d03
                     'added tracking request for "%s"', nickname)
ac7d03
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
ac7d03
index 855056dc1fa20e813d82ecc5090a14cfc4f91831..96fdadf751ef619e198a861d9f62440c98f3abae 100644
ac7d03
--- a/ipaserver/install/server/upgrade.py
ac7d03
+++ b/ipaserver/install/server/upgrade.py
ac7d03
@@ -974,6 +974,21 @@ def certificate_renewal_update(ca, ds, http):
ac7d03
         root_logger.info('CA is not configured')
ac7d03
         return False
ac7d03
 
ac7d03
+    db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
ac7d03
+    for nickname, _trust_flags in db.list_certs():
ac7d03
+        if nickname.startswith('caSigningCert cert-pki-ca '):
ac7d03
+            requests.append(
ac7d03
+                {
ac7d03
+                    'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
ac7d03
+                    'cert-nickname': nickname,
ac7d03
+                    'ca': 'dogtag-ipa-ca-renew-agent',
ac7d03
+                    'cert-presave-command': template % 'stop_pkicad',
ac7d03
+                    'cert-postsave-command':
ac7d03
+                        (template % ('renew_ca_cert "%s"' % nickname)),
ac7d03
+                    'template-profile': 'caCACert',
ac7d03
+                }
ac7d03
+            )
ac7d03
+
ac7d03
     # State not set, lets see if we are already configured
ac7d03
     for request in requests:
ac7d03
         request_id = certmonger.get_request_id(request)
ac7d03
@@ -998,6 +1013,7 @@ def certificate_renewal_update(ca, ds, http):
ac7d03
     ca.configure_renewal()
ac7d03
     ca.configure_agent_renewal()
ac7d03
     ca.track_servercert()
ac7d03
+    ca.add_lightweight_ca_tracking_requests()
ac7d03
     ds.start_tracking_certificates(serverid)
ac7d03
     http.start_tracking_certificates()
ac7d03
 
ac7d03
-- 
ac7d03
2.9.3
ac7d03