diff --git a/src/ipahealthcheck/dogtag/ca.py b/src/ipahealthcheck/dogtag/ca.py index 868876f1..b0a9ea13 100644 --- a/src/ipahealthcheck/dogtag/ca.py +++ b/src/ipahealthcheck/dogtag/ca.py @@ -122,8 +122,21 @@ def check(self): found = False for cert in certs: if DN(cert.subject) == ipa_subject: - found = True - break + if DN(cert.issuer) != ipa_subject: + # We found the CA cert but it was issued by an external + # CA so we can't check it by serial number. + yield Result(self, constants.SUCCESS, + key='cert_show_1', + subject=str(ipa_subject), + issuer=str(DN(cert.issuer)), + path=paths.IPA_CA_CRT, + msg='The CA certificate was externally ' + 'signed by {issuer}. Skipping ' + 'serial number check.') + return + else: + found = True + break if not found: yield Result(self, constants.ERROR, diff --git a/tests/test_dogtag_connectivity.py b/tests/test_dogtag_connectivity.py index d81e5988..4e6b7309 100644 --- a/tests/test_dogtag_connectivity.py +++ b/tests/test_dogtag_connectivity.py @@ -16,11 +16,21 @@ from ipapython.dn import DN +default_subject_base = [{ + 'result': + { + 'ipacertificatesubjectbase': [f'O={m_api.env.realm}'], + }, +}] + + class IPACertificate: def __init__(self, serial_number=1, - subject='CN=Certificate Authority, O=%s' % m_api.env.realm): + subject='CN=Certificate Authority, O=%s' % m_api.env.realm, + issuer='CN=Certificate Authority, O=%s' % m_api.env.realm): self.serial_number = serial_number self.subject = subject + self.issuer = issuer def __eq__(self, other): return self.serial_number == other.serial_number @@ -279,3 +289,32 @@ def test_ca_connection_not_found(self, mock_load_cert, mock_ca_subject): assert result.kw['msg'] == ( 'The CA certificate with subject {subject} was not found in {path}' ) + + @patch('ipalib.x509.load_certificate_list_from_file') + @patch('ipaserver.install.ca.lookup_ca_subject') + def test_cacert_external(self, mock_ca_subject, mock_load_cert): + """Nothing to check if the master is CALess""" + + ipa_subject = DN(('cn', 'Certificate Authority'), + f'O={m_api.env.realm}') + mock_ca_subject.return_value = ipa_subject + m_api.Command.config_show.side_effect = default_subject_base + + mock_load_cert.return_value = [ + IPACertificate(1, 'CN=External Root', 'CN=External Root'), + IPACertificate(2, 'CN=External Root', 'CN=External CA'), + IPACertificate(3, ipa_subject, 'CN=External CA') + ] + + framework = object() + registry.initialize(framework, config) + f = DogtagCertsConnectivityCheck(registry) + + self.results = capture_results(f) + + assert len(self.results) == 1 + result = self.results.results[0] + + assert result.result == constants.SUCCESS + assert result.source == 'ipahealthcheck.dogtag.ca' + assert result.check == 'DogtagCertsConnectivityCheck'