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