cainstance: use correct profile for lightweight CA certificates

Use Dogtag's `caCACert` CA certificate profile rather than the
`ipaCACertRenewal` virtual profile for lightweight CA certificates.

The `ipaCACertRenewal` virtual profile adds special handling of externally
signed CA certificates and LDAP replication of issued certificates on top
of `caCACert`, neither of which is relevant for lightweight CA
certificates.

Remove all of the special casing of lightweight CA certificates from
dogtag-ipa-ca-renew-agent-submit.

Make sure existing lightweight CA certmonger tracking requests are updated
on server upgrade.

https://pagure.io/freeipa/issue/5799

Reviewed-By: David Kupka <dkupka@redhat.com>
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
This commit is contained in:
Jan Cholasta 2017-02-28 10:58:28 +00:00 committed by David Kupka
parent 5abd9bb996
commit 09a49ad458
3 changed files with 23 additions and 36 deletions

View File

@ -98,25 +98,7 @@ def get_nickname():
DN('CN=IPA RA', subject_base): 'ipaCert', DN('CN=IPA RA', subject_base): 'ipaCert',
} }
try: return nickname_by_subject_dn.get(DN(subject))
return nickname_by_subject_dn[DN(subject)]
except KeyError:
cas = api.Command.ca_find(ipacasubjectdn=DN(subject))['result']
if len(cas) == 0:
return None
return 'caSigningCert cert-pki-ca {}'.format(cas[0]['ipacaid'][0])
def is_lightweight_ca():
nickname = get_nickname() or ''
return nickname != IPA_CA_NICKNAME and nickname.startswith(IPA_CA_NICKNAME)
def is_renewable():
cert = os.environ.get('CERTMONGER_CERTIFICATE')
if not cert:
return False
else:
return x509.is_self_signed(cert) or is_lightweight_ca()
def is_replicated(): def is_replicated():
@ -276,11 +258,6 @@ def store_cert():
if not cert: if not cert:
return (REJECTED, "New certificate requests not supported") return (REJECTED, "New certificate requests not supported")
if is_lightweight_ca():
# Lightweight CAs are updated in Dogtag's NSSDB
# by Dogtag itself, so do not store it
return (ISSUED, cert)
dercert = x509.normalize_certificate(cert) dercert = x509.normalize_certificate(cert)
dn = DN(('cn', nickname), ('cn', 'ca_renewal'), dn = DN(('cn', nickname), ('cn', 'ca_renewal'),
@ -405,12 +382,6 @@ def retrieve_cert_continuous():
if old_cert: if old_cert:
old_cert = x509.normalize_certificate(old_cert) old_cert = x509.normalize_certificate(old_cert)
if is_lightweight_ca():
# Lightweight CAs are updated in Dogtag's NSSDB
# by Dogtag itself, so do not try to retrieve it.
# Everything is fine as is.
return (ISSUED, os.environ.get('CERTMONGER_CERTIFICATE'))
result = call_handler(retrieve_or_reuse_cert) result = call_handler(retrieve_or_reuse_cert)
if result[0] != ISSUED: if result[0] != ISSUED:
return result return result
@ -466,12 +437,13 @@ def renew_ca_cert():
cert = os.environ.get('CERTMONGER_CERTIFICATE') cert = os.environ.get('CERTMONGER_CERTIFICATE')
if not cert: if not cert:
return (REJECTED, "New certificate requests not supported") return (REJECTED, "New certificate requests not supported")
is_self_signed = x509.is_self_signed(cert)
operation = os.environ.get('CERTMONGER_OPERATION') operation = os.environ.get('CERTMONGER_OPERATION')
if operation == 'SUBMIT': if operation == 'SUBMIT':
state = 'retrieve' state = 'retrieve'
if is_renewable() and is_renewal_master(): if is_self_signed and is_renewal_master():
state = 'request' state = 'request'
elif operation == 'POLL': elif operation == 'POLL':
cookie = os.environ.get('CERTMONGER_CA_COOKIE') cookie = os.environ.get('CERTMONGER_CA_COOKIE')
@ -489,7 +461,7 @@ def renew_ca_cert():
if state == 'retrieve': if state == 'retrieve':
result = call_handler(retrieve_cert) result = call_handler(retrieve_cert)
if result[0] == REJECTED and not is_renewable(): if result[0] == REJECTED and not is_self_signed:
syslog.syslog(syslog.LOG_ALERT, syslog.syslog(syslog.LOG_ALERT,
"Certificate with subject '%s' is about to expire, " "Certificate with subject '%s' is about to expire, "
"use ipa-cacert-manage to renew it" "use ipa-cacert-manage to renew it"

View File

@ -436,7 +436,7 @@ class CAInstance(DogtagInstance):
self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry) self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry)
self.step("configuring certmonger renewal for lightweight CAs", self.step("configuring certmonger renewal for lightweight CAs",
self.__add_lightweight_ca_tracking_requests) self.add_lightweight_ca_tracking_requests)
if ra_only: if ra_only:
runtime = None runtime = None
@ -1246,7 +1246,7 @@ class CAInstance(DogtagInstance):
os.chmod(keyfile, 0o600) os.chmod(keyfile, 0o600)
os.chown(keyfile, pent.pw_uid, pent.pw_gid) os.chown(keyfile, pent.pw_uid, pent.pw_gid)
def __add_lightweight_ca_tracking_requests(self): def add_lightweight_ca_tracking_requests(self):
try: try:
lwcas = api.Backend.ldap2.get_entries( lwcas = api.Backend.ldap2.get_entries(
base_dn=api.env.basedn, base_dn=api.env.basedn,
@ -1810,11 +1810,10 @@ def add_lightweight_ca_tracking_requests(logger, lwcas):
pin=certmonger.get_pin('internal'), pin=certmonger.get_pin('internal'),
nickname=nickname, nickname=nickname,
ca=ipalib.constants.RENEWAL_CA_NAME, ca=ipalib.constants.RENEWAL_CA_NAME,
profile='caCACert',
pre_command='stop_pkicad', pre_command='stop_pkicad',
post_command='renew_ca_cert "%s"' % nickname, post_command='renew_ca_cert "%s"' % nickname,
) )
request_id = certmonger.get_request_id(criteria)
certmonger.modify(request_id, profile='ipaCACertRenewal')
logger.debug( logger.debug(
'Lightweight CA renewal: ' 'Lightweight CA renewal: '
'added tracking request for "%s"', nickname) 'added tracking request for "%s"', nickname)

View File

@ -974,6 +974,21 @@ def certificate_renewal_update(ca, ds, http):
root_logger.info('CA is not configured') root_logger.info('CA is not configured')
return False return False
db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
for nickname, _trust_flags in db.list_certs():
if nickname.startswith('caSigningCert cert-pki-ca '):
requests.append(
{
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
'cert-nickname': nickname,
'ca': 'dogtag-ipa-ca-renew-agent',
'cert-presave-command': template % 'stop_pkicad',
'cert-postsave-command':
(template % ('renew_ca_cert "%s"' % nickname)),
'template-profile': 'caCACert',
}
)
# State not set, lets see if we are already configured # State not set, lets see if we are already configured
for request in requests: for request in requests:
request_id = certmonger.get_request_id(request) request_id = certmonger.get_request_id(request)
@ -998,6 +1013,7 @@ def certificate_renewal_update(ca, ds, http):
ca.configure_renewal() ca.configure_renewal()
ca.configure_agent_renewal() ca.configure_agent_renewal()
ca.track_servercert() ca.track_servercert()
ca.add_lightweight_ca_tracking_requests()
ds.start_tracking_certificates(serverid) ds.start_tracking_certificates(serverid)
http.start_tracking_certificates() http.start_tracking_certificates()