mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-11 00:31:56 -06:00
Do not renew externally-signed CA as self-signed
Commit 49cf5ec64b
fixed a bug that
prevented migration from externally-signed to self-signed IPA CA.
But it introduced a subtle new issue: certmonger-initiated renewal
renews an externally-signed IPA CA as a self-signed CA.
To resolve this issue, introduce the `--force-self-signed' flag for
the dogtag-ipa-ca-renew-agent script. Add another certmonger CA
definition that calls this script with the `--force-self-signed'
flag. Update dogtag-ipa-ca-renew-agent to only issue a self-signed
CA certificate if the existing certificate is self-signed or if
`--force-self-signed' was given. Update `ipa-cacert-manage renew'
to supply `--force-self-signed' when appropriate.
As a result of these changes, certmonger-initiated renewal of an
externally-signed IPA CA certificate will not issue a self-signed
certificate.
Fixes: https://pagure.io/freeipa/issue/8176
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
parent
8e71605c54
commit
769180c2c6
@ -402,7 +402,7 @@ def retrieve_cert(**kwargs):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def renew_ca_cert(reuse_existing, **kwargs):
|
def renew_ca_cert(reuse_existing, force_self_signed, **kwargs):
|
||||||
"""
|
"""
|
||||||
This is used for automatic CA certificate renewal.
|
This is used for automatic CA certificate renewal.
|
||||||
"""
|
"""
|
||||||
@ -420,7 +420,8 @@ def renew_ca_cert(reuse_existing, **kwargs):
|
|||||||
if operation == 'SUBMIT':
|
if operation == 'SUBMIT':
|
||||||
state = 'retrieve'
|
state = 'retrieve'
|
||||||
|
|
||||||
if not reuse_existing and is_renewal_master():
|
if (is_self_signed or force_self_signed) \
|
||||||
|
and not reuse_existing and is_renewal_master():
|
||||||
state = 'request'
|
state = 'request'
|
||||||
|
|
||||||
csr_file = paths.IPA_CA_CSR
|
csr_file = paths.IPA_CA_CSR
|
||||||
@ -473,7 +474,9 @@ def renew_ca_cert(reuse_existing, **kwargs):
|
|||||||
def main():
|
def main():
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'reuse_existing': False,
|
'reuse_existing': False,
|
||||||
|
'force_self_signed': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sys.argv.remove('--reuse-existing')
|
sys.argv.remove('--reuse-existing')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -481,6 +484,13 @@ def main():
|
|||||||
else:
|
else:
|
||||||
kwargs['reuse_existing'] = True
|
kwargs['reuse_existing'] = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
sys.argv.remove('--force-self-signed')
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
kwargs['force_self_signed'] = True
|
||||||
|
|
||||||
operation = os.environ.get('CERTMONGER_OPERATION')
|
operation = os.environ.get('CERTMONGER_OPERATION')
|
||||||
if operation not in ('SUBMIT', 'POLL'):
|
if operation not in ('SUBMIT', 'POLL'):
|
||||||
return OPERATION_NOT_SUPPORTED_BY_HELPER
|
return OPERATION_NOT_SUPPORTED_BY_HELPER
|
||||||
|
@ -310,6 +310,7 @@ IPA_CA_RECORD = "ipa-ca"
|
|||||||
IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
|
IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
|
||||||
RENEWAL_CA_NAME = 'dogtag-ipa-ca-renew-agent'
|
RENEWAL_CA_NAME = 'dogtag-ipa-ca-renew-agent'
|
||||||
RENEWAL_REUSE_CA_NAME = 'dogtag-ipa-ca-renew-agent-reuse'
|
RENEWAL_REUSE_CA_NAME = 'dogtag-ipa-ca-renew-agent-reuse'
|
||||||
|
RENEWAL_SELFSIGNED_CA_NAME = 'dogtag-ipa-ca-renew-agent-selfsigned'
|
||||||
# The RA agent cert is used for client cert authentication. In the past IPA
|
# The RA agent cert is used for client cert authentication. In the past IPA
|
||||||
# used caServerCert profile, which adds clientAuth and serverAuth EKU. The
|
# used caServerCert profile, which adds clientAuth and serverAuth EKU. The
|
||||||
# serverAuth EKU caused trouble with NamedConstraints, see RHBZ#1670239.
|
# serverAuth EKU caused trouble with NamedConstraints, see RHBZ#1670239.
|
||||||
|
@ -424,7 +424,7 @@ class CAInstance(DogtagInstance):
|
|||||||
if self.external != 1:
|
if self.external != 1:
|
||||||
if not has_ra_cert:
|
if not has_ra_cert:
|
||||||
self.step("configure certmonger for renewals",
|
self.step("configure certmonger for renewals",
|
||||||
self.configure_certmonger_renewal)
|
self.configure_certmonger_renewal_helpers)
|
||||||
if not self.clone:
|
if not self.clone:
|
||||||
self.step("requesting RA certificate from CA", self.__request_ra_certificate)
|
self.step("requesting RA certificate from CA", self.__request_ra_certificate)
|
||||||
elif promote:
|
elif promote:
|
||||||
@ -998,7 +998,7 @@ class CAInstance(DogtagInstance):
|
|||||||
obj = bus.get_object('org.fedorahosted.certmonger',
|
obj = bus.get_object('org.fedorahosted.certmonger',
|
||||||
'/org/fedorahosted/certmonger')
|
'/org/fedorahosted/certmonger')
|
||||||
iface = dbus.Interface(obj, 'org.fedorahosted.certmonger')
|
iface = dbus.Interface(obj, 'org.fedorahosted.certmonger')
|
||||||
for suffix in ['', '-reuse']:
|
for suffix in ['', '-reuse', '-selfsigned']:
|
||||||
name = ipalib.constants.RENEWAL_CA_NAME + suffix
|
name = ipalib.constants.RENEWAL_CA_NAME + suffix
|
||||||
path = iface.find_ca_by_nickname(name)
|
path = iface.find_ca_by_nickname(name)
|
||||||
if path:
|
if path:
|
||||||
|
@ -290,7 +290,7 @@ class DogtagInstance(service.Service):
|
|||||||
fd.write(template)
|
fd.write(template)
|
||||||
os.fchmod(fd.fileno(), 0o644)
|
os.fchmod(fd.fileno(), 0o644)
|
||||||
|
|
||||||
def configure_certmonger_renewal(self):
|
def configure_certmonger_renewal_helpers(self):
|
||||||
"""
|
"""
|
||||||
Create a new CA type for certmonger that will retrieve updated
|
Create a new CA type for certmonger that will retrieve updated
|
||||||
certificates from the dogtag master server.
|
certificates from the dogtag master server.
|
||||||
@ -306,7 +306,11 @@ class DogtagInstance(service.Service):
|
|||||||
obj = bus.get_object('org.fedorahosted.certmonger',
|
obj = bus.get_object('org.fedorahosted.certmonger',
|
||||||
'/org/fedorahosted/certmonger')
|
'/org/fedorahosted/certmonger')
|
||||||
iface = dbus.Interface(obj, 'org.fedorahosted.certmonger')
|
iface = dbus.Interface(obj, 'org.fedorahosted.certmonger')
|
||||||
for suffix, args in [('', ''), ('-reuse', ' --reuse-existing')]:
|
for suffix, args in [
|
||||||
|
('', ''),
|
||||||
|
('-reuse', ' --reuse-existing'),
|
||||||
|
('-selfsigned', ' --force-self-signed'),
|
||||||
|
]:
|
||||||
name = RENEWAL_CA_NAME + suffix
|
name = RENEWAL_CA_NAME + suffix
|
||||||
path = iface.find_ca_by_nickname(name)
|
path = iface.find_ca_by_nickname(name)
|
||||||
if not path:
|
if not path:
|
||||||
|
@ -24,7 +24,9 @@ import os
|
|||||||
from optparse import OptionGroup # pylint: disable=deprecated-module
|
from optparse import OptionGroup # pylint: disable=deprecated-module
|
||||||
import gssapi
|
import gssapi
|
||||||
|
|
||||||
from ipalib.constants import RENEWAL_CA_NAME, RENEWAL_REUSE_CA_NAME, IPA_CA_CN
|
from ipalib.constants import (
|
||||||
|
RENEWAL_CA_NAME, RENEWAL_REUSE_CA_NAME, RENEWAL_SELFSIGNED_CA_NAME,
|
||||||
|
IPA_CA_CN)
|
||||||
from ipalib.install import certmonger, certstore
|
from ipalib.install import certmonger, certstore
|
||||||
from ipapython import admintool, ipautil
|
from ipapython import admintool, ipautil
|
||||||
from ipapython.certdb import (EMPTY_TRUST_FLAGS,
|
from ipapython.certdb import (EMPTY_TRUST_FLAGS,
|
||||||
@ -223,7 +225,7 @@ class CACertManage(admintool.AdminTool):
|
|||||||
except errors.NotFound:
|
except errors.NotFound:
|
||||||
raise admintool.ScriptError("CA renewal master not found")
|
raise admintool.ScriptError("CA renewal master not found")
|
||||||
|
|
||||||
self.resubmit_request()
|
self.resubmit_request(RENEWAL_SELFSIGNED_CA_NAME)
|
||||||
|
|
||||||
db = certs.CertDB(api.env.realm, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
|
db = certs.CertDB(api.env.realm, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
|
||||||
cert = db.get_cert_from_db(self.cert_nickname)
|
cert = db.get_cert_from_db(self.cert_nickname)
|
||||||
|
@ -131,7 +131,7 @@ class KRAInstance(DogtagInstance):
|
|||||||
self.step("enabling ephemeral requests", self.enable_ephemeral)
|
self.step("enabling ephemeral requests", self.enable_ephemeral)
|
||||||
self.step("restarting KRA", self.restart_instance)
|
self.step("restarting KRA", self.restart_instance)
|
||||||
self.step("configure certmonger for renewals",
|
self.step("configure certmonger for renewals",
|
||||||
self.configure_certmonger_renewal)
|
self.configure_certmonger_renewal_helpers)
|
||||||
self.step("configure certificate renewals", self.configure_renewal)
|
self.step("configure certificate renewals", self.configure_renewal)
|
||||||
self.step("configure HTTP to proxy connections",
|
self.step("configure HTTP to proxy connections",
|
||||||
self.http_proxy)
|
self.http_proxy)
|
||||||
|
@ -1032,6 +1032,9 @@ def certificate_renewal_update(ca, kra, ds, http):
|
|||||||
Update certmonger certificate renewal configuration.
|
Update certmonger certificate renewal configuration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# First ensure the renewal helpers are defined.
|
||||||
|
ca.configure_certmonger_renewal_helpers()
|
||||||
|
|
||||||
template = paths.CERTMONGER_COMMAND_TEMPLATE
|
template = paths.CERTMONGER_COMMAND_TEMPLATE
|
||||||
serverid = ipaldap.realm_to_serverid(api.env.realm)
|
serverid = ipaldap.realm_to_serverid(api.env.realm)
|
||||||
|
|
||||||
@ -1148,7 +1151,6 @@ def certificate_renewal_update(ca, kra, ds, http):
|
|||||||
logger.info("Removing %s", filename)
|
logger.info("Removing %s", filename)
|
||||||
ipautil.remove_file(filename)
|
ipautil.remove_file(filename)
|
||||||
|
|
||||||
ca.configure_certmonger_renewal()
|
|
||||||
ca.configure_renewal()
|
ca.configure_renewal()
|
||||||
ca.configure_agent_renewal()
|
ca.configure_agent_renewal()
|
||||||
ca.add_lightweight_ca_tracking_requests()
|
ca.add_lightweight_ca_tracking_requests()
|
||||||
|
Loading…
Reference in New Issue
Block a user