Blame SOURCES/0010-Add-tests-for-certificate-mismatch-detection.patch

f00d0e
From 94ca49d991b3f5bb404533f84970a1b2485d9cc8 Mon Sep 17 00:00:00 2001
f00d0e
From: Antonio Torres <antorres@redhat.com>
f00d0e
Date: Fri, 23 Apr 2021 17:48:14 +0200
f00d0e
Subject: [PATCH] Add tests for certificate mismatch detection
f00d0e
f00d0e
Add tests for the IPACertMatchCheck and IPADogtagCertsMatchCheck plugins.
f00d0e
f00d0e
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1886770
f00d0e
Signed-off-by: Antonio Torres <antorres@redhat.com>
f00d0e
---
f00d0e
 tests/test_ipa_cert_match.py | 282 +++++++++++++++++++++++++++++++++++
f00d0e
 1 file changed, 282 insertions(+)
f00d0e
 create mode 100644 tests/test_ipa_cert_match.py
f00d0e
f00d0e
diff --git a/tests/test_ipa_cert_match.py b/tests/test_ipa_cert_match.py
f00d0e
new file mode 100644
f00d0e
index 0000000..460e61a
f00d0e
--- /dev/null
f00d0e
+++ b/tests/test_ipa_cert_match.py
f00d0e
@@ -0,0 +1,282 @@
f00d0e
+#
f00d0e
+# Copyright (C) 2021 FreeIPA Contributors see COPYING for license
f00d0e
+#
f00d0e
+
f00d0e
+from util import capture_results, m_api, CAInstance, KRAInstance
f00d0e
+from base import BaseTest
f00d0e
+from ipahealthcheck.core import config, constants
f00d0e
+from ipahealthcheck.ipa.plugin import registry
f00d0e
+from ipahealthcheck.ipa.certs import IPACertMatchCheck
f00d0e
+from ipahealthcheck.ipa.certs import IPADogtagCertsMatchCheck
f00d0e
+from unittest.mock import Mock, patch
f00d0e
+
f00d0e
+from ipalib import errors
f00d0e
+from ipapython.dn import DN
f00d0e
+from ipapython.ipaldap import LDAPClient, LDAPEntry
f00d0e
+
f00d0e
+
f00d0e
+class IPACertificate:
f00d0e
+    def __init__(self, serial_number=1):
f00d0e
+        self.serial_number = serial_number
f00d0e
+
f00d0e
+    def __eq__(self, other):
f00d0e
+        return self.serial_number == other.serial_number
f00d0e
+
f00d0e
+    def __hash__(self):
f00d0e
+        return hash(self.serial_number)
f00d0e
+
f00d0e
+
f00d0e
+class mock_ldap:
f00d0e
+    SCOPE_BASE = 1
f00d0e
+    SCOPE_ONELEVEL = 2
f00d0e
+    SCOPE_SUBTREE = 4
f00d0e
+
f00d0e
+    def __init__(self, entries):
f00d0e
+        """Initialize the results that we will return from get_entry"""
f00d0e
+        self.results = {entry.dn: entry for entry in entries}
f00d0e
+
f00d0e
+    def get_entry(self, dn, attrs_list=None, time_limit=None,
f00d0e
+                  size_limit=None, get_effective_rights=False):
f00d0e
+        if self.results is None:
f00d0e
+            raise errors.NotFound(reason='test')
f00d0e
+        return self.results[dn]
f00d0e
+
f00d0e
+    def get_entries(self, base_dn, scope=SCOPE_SUBTREE, filter=None,
f00d0e
+                    attrs_list=None, get_effective_rights=False, **kwargs):
f00d0e
+        if self.results is None:
f00d0e
+            raise errors.NotFound(reason='test')
f00d0e
+        return self.results.values()
f00d0e
+
f00d0e
+
f00d0e
+class mock_ldap_conn:
f00d0e
+    def set_option(self, option, invalue):
f00d0e
+        pass
f00d0e
+
f00d0e
+    def search_s(self, base, scope, filterstr=None,
f00d0e
+                 attrlist=None, attrsonly=0):
f00d0e
+        return tuple()
f00d0e
+
f00d0e
+
f00d0e
+class mock_CertDB:
f00d0e
+    def __init__(self, trust):
f00d0e
+        """A dict of nickname + NSSdb trust flags"""
f00d0e
+        self.trust = trust
f00d0e
+        self.secdir = '/foo/bar/testdir'
f00d0e
+
f00d0e
+    def get_cert_from_db(self, nickname):
f00d0e
+        if nickname not in self.trust.keys():
f00d0e
+            raise errors.NotFound(reason='test')
f00d0e
+        return IPACertificate()
f00d0e
+
f00d0e
+    def run_certutil(self, args, capture_output):
f00d0e
+        class RunResult:
f00d0e
+            def __init__(self, output):
f00d0e
+                self.raw_output = output
f00d0e
+
f00d0e
+        return RunResult(b'test output')
f00d0e
+
f00d0e
+
f00d0e
+class TestIPACertMatch(BaseTest):
f00d0e
+    patches = {
f00d0e
+        'ldap.initialize':
f00d0e
+        Mock(return_value=mock_ldap_conn())
f00d0e
+    }
f00d0e
+
f00d0e
+    @patch('ipalib.x509.load_certificate_list_from_file')
f00d0e
+    @patch('ipaserver.install.certs.CertDB')
f00d0e
+    def test_certs_match_ok(self, mock_certdb, mock_load_cert):
f00d0e
+        """ Ensure match check is ok"""
f00d0e
+        fake_conn = LDAPClient('ldap://localhost', no_schema=True)
f00d0e
+        cacertentry = LDAPEntry(fake_conn,
f00d0e
+                                DN('cn=%s IPA CA' % m_api.env.realm,
f00d0e
+                                   'cn=certificates,cn=ipa,cn=etc',
f00d0e
+                                    m_api.env.basedn),
f00d0e
+                                CACertificate=[IPACertificate()])
f00d0e
+        trust = {
f00d0e
+            ('%s IPA CA' % m_api.env.realm): 'u,u,u'
f00d0e
+        }
f00d0e
+
f00d0e
+        mock_certdb.return_value = mock_CertDB(trust)
f00d0e
+        mock_load_cert.return_value = [IPACertificate()]
f00d0e
+
f00d0e
+        framework = object()
f00d0e
+        registry.initialize(framework, config.Config())
f00d0e
+        f = IPACertMatchCheck(registry)
f00d0e
+        f.conn = mock_ldap([cacertentry])
f00d0e
+        self.results = capture_results(f)
f00d0e
+
f00d0e
+        assert len(self.results) == 3
f00d0e
+        for result in self.results.results:
f00d0e
+            assert result.result == constants.SUCCESS
f00d0e
+            assert result.source == 'ipahealthcheck.ipa.certs'
f00d0e
+            assert result.check == 'IPACertMatchCheck'
f00d0e
+
f00d0e
+    @patch('ipalib.x509.load_certificate_list_from_file')
f00d0e
+    @patch('ipaserver.install.certs.CertDB')
f00d0e
+    def test_etc_cacert_mismatch(self, mock_certdb, mock_load_cert):
f00d0e
+        """ Test mismatch with /etc/ipa/ca.crt """
f00d0e
+        fake_conn = LDAPClient('ldap://localhost', no_schema=True)
f00d0e
+        cacertentry = LDAPEntry(fake_conn,
f00d0e
+                                DN('cn=%s IPA CA' % m_api.env.realm,
f00d0e
+                                   'cn=certificates,cn=ipa,cn=etc',
f00d0e
+                                    m_api.env.basedn),
f00d0e
+                                CACertificate=[IPACertificate()])
f00d0e
+        trust = {
f00d0e
+            ('%s IPA CA' % m_api.env.realm): 'u,u,u'
f00d0e
+        }
f00d0e
+
f00d0e
+        mock_certdb.return_value = mock_CertDB(trust)
f00d0e
+        mock_load_cert.return_value = [IPACertificate(serial_number=2)]
f00d0e
+
f00d0e
+        framework = object()
f00d0e
+        registry.initialize(framework, config.Config())
f00d0e
+        f = IPACertMatchCheck(registry)
f00d0e
+        f.conn = mock_ldap([cacertentry])
f00d0e
+        self.results = capture_results(f)
f00d0e
+
f00d0e
+        assert len(self.results) == 3
f00d0e
+        result = self.results.results[0]
f00d0e
+        assert result.result == constants.ERROR
f00d0e
+        assert result.source == 'ipahealthcheck.ipa.certs'
f00d0e
+        assert result.check == 'IPACertMatchCheck'
f00d0e
+
f00d0e
+    @patch('ipaserver.install.cainstance.CAInstance')
f00d0e
+    def test_cacert_caless(self, mock_cainstance):
f00d0e
+        """Nothing to check if the master is CALess"""
f00d0e
+
f00d0e
+        mock_cainstance.return_value = CAInstance(False)
f00d0e
+
f00d0e
+        framework = object()
f00d0e
+        registry.initialize(framework, config)
f00d0e
+        f = IPACertMatchCheck(registry)
f00d0e
+
f00d0e
+        self.results = capture_results(f)
f00d0e
+
f00d0e
+        assert len(self.results) == 0
f00d0e
+
f00d0e
+
f00d0e
+class TestIPADogtagCertMatch(BaseTest):
f00d0e
+    patches = {
f00d0e
+        'ipaserver.install.krainstance.KRAInstance':
f00d0e
+        Mock(return_value=KRAInstance()),
f00d0e
+    }
f00d0e
+
f00d0e
+    @patch('ipaserver.install.certs.CertDB')
f00d0e
+    def test_certs_match_ok(self, mock_certdb):
f00d0e
+        """ Ensure match check is ok"""
f00d0e
+        fake_conn = LDAPClient('ldap://localhost', no_schema=True)
f00d0e
+        pkidbentry = LDAPEntry(fake_conn,
f00d0e
+                               DN('uid=pkidbuser,ou=people,o=ipaca'),
f00d0e
+                               userCertificate=[IPACertificate()],
f00d0e
+                               subjectName=['test'])
f00d0e
+        casignentry = LDAPEntry(fake_conn,
f00d0e
+                                DN('cn=%s IPA CA' % m_api.env.realm,
f00d0e
+                                   'cn=certificates,cn=ipa,cn=etc',
f00d0e
+                                    m_api.env.basedn),
f00d0e
+                                CACertificate=[IPACertificate()],
f00d0e
+                                userCertificate=[IPACertificate()],
f00d0e
+                                subjectName=['test'])
f00d0e
+        ldap_entries = [pkidbentry, casignentry]
f00d0e
+        trust = {
f00d0e
+            'ocspSigningCert cert-pki-ca': 'u,u,u',
f00d0e
+            'caSigningCert cert-pki-ca': 'u,u,u',
f00d0e
+            'subsystemCert cert-pki-ca': 'u,u,u',
f00d0e
+            'auditSigningCert cert-pki-ca': 'u,u,Pu',
f00d0e
+            'Server-Cert cert-pki-ca': 'u,u,u',
f00d0e
+            'transportCert cert-pki-kra': 'u,u,u',
f00d0e
+            'storageCert cert-pki-kra': 'u,u,u',
f00d0e
+            'auditSigningCert cert-pki-kra': 'u,u,Pu',
f00d0e
+        }
f00d0e
+
f00d0e
+        dogtag_entries_subjects = (
f00d0e
+            'CN=OCSP Subsystem,O=%s' % m_api.env.realm,
f00d0e
+            'CN=CA Subsystem,O=%s' % m_api.env.realm,
f00d0e
+            'CN=CA Audit,O=%s' % m_api.env.realm,
f00d0e
+            'CN=%s,O=%s' % (m_api.env.host, m_api.env.realm),
f00d0e
+            'CN=KRA Transport Certificate,O=%s' % m_api.env.realm,
f00d0e
+            'CN=KRA Storage Certificate,O=%s' % m_api.env.realm,
f00d0e
+            'CN=KRA Audit,O=%s' % m_api.env.realm,
f00d0e
+        )
f00d0e
+
f00d0e
+        for i, subject in enumerate(dogtag_entries_subjects):
f00d0e
+            entry = LDAPEntry(fake_conn,
f00d0e
+                              DN('cn=%i,ou=certificateRepository' % i,
f00d0e
+                                 'ou=ca,o=ipaca'),
f00d0e
+                              userCertificate=[IPACertificate()],
f00d0e
+                              subjectName=[subject])
f00d0e
+            ldap_entries.append(entry)
f00d0e
+
f00d0e
+        mock_certdb.return_value = mock_CertDB(trust)
f00d0e
+
f00d0e
+        framework = object()
f00d0e
+        registry.initialize(framework, config.Config())
f00d0e
+        f = IPADogtagCertsMatchCheck(registry)
f00d0e
+        f.conn = mock_ldap(ldap_entries)
f00d0e
+        self.results = capture_results(f)
f00d0e
+
f00d0e
+        assert len(self.results) == 3
f00d0e
+        for result in self.results.results:
f00d0e
+            assert result.result == constants.SUCCESS
f00d0e
+            assert result.source == 'ipahealthcheck.ipa.certs'
f00d0e
+            assert result.check == 'IPADogtagCertsMatchCheck'
f00d0e
+
f00d0e
+    @patch('ipaserver.install.certs.CertDB')
f00d0e
+    def test_certs_mismatch(self, mock_certdb):
f00d0e
+        """ Ensure mismatches are detected"""
f00d0e
+        fake_conn = LDAPClient('ldap://localhost', no_schema=True)
f00d0e
+        pkidbentry = LDAPEntry(fake_conn,
f00d0e
+                               DN('uid=pkidbuser,ou=people,o=ipaca'),
f00d0e
+                               userCertificate=[IPACertificate(
f00d0e
+                                   serial_number=2
f00d0e
+                               )],
f00d0e
+                               subjectName=['test'])
f00d0e
+        casignentry = LDAPEntry(fake_conn,
f00d0e
+                                DN('cn=%s IPA CA' % m_api.env.realm,
f00d0e
+                                   'cn=certificates,cn=ipa,cn=etc',
f00d0e
+                                    m_api.env.basedn),
f00d0e
+                                CACertificate=[IPACertificate()],
f00d0e
+                                userCertificate=[IPACertificate()],
f00d0e
+                                subjectName=['test'])
f00d0e
+        ldap_entries = [pkidbentry, casignentry]
f00d0e
+        trust = {
f00d0e
+            'ocspSigningCert cert-pki-ca': 'u,u,u',
f00d0e
+            'caSigningCert cert-pki-ca': 'u,u,u',
f00d0e
+            'subsystemCert cert-pki-ca': 'u,u,u',
f00d0e
+            'auditSigningCert cert-pki-ca': 'u,u,Pu',
f00d0e
+            'Server-Cert cert-pki-ca': 'u,u,u',
f00d0e
+            'transportCert cert-pki-kra': 'u,u,u',
f00d0e
+            'storageCert cert-pki-kra': 'u,u,u',
f00d0e
+            'auditSigningCert cert-pki-kra': 'u,u,Pu',
f00d0e
+        }
f00d0e
+
f00d0e
+        dogtag_entries_subjects = (
f00d0e
+            'CN=OCSP Subsystem,O=%s' % m_api.env.realm,
f00d0e
+            'CN=CA Subsystem,O=%s' % m_api.env.realm,
f00d0e
+            'CN=CA Audit,O=%s' % m_api.env.realm,
f00d0e
+            'CN=%s,O=%s' % (m_api.env.host, m_api.env.realm),
f00d0e
+            'CN=KRA Transport Certificate,O=%s' % m_api.env.realm,
f00d0e
+            'CN=KRA Storage Certificate,O=%s' % m_api.env.realm,
f00d0e
+            'CN=KRA Audit,O=%s' % m_api.env.realm,
f00d0e
+        )
f00d0e
+
f00d0e
+        for i, subject in enumerate(dogtag_entries_subjects):
f00d0e
+            entry = LDAPEntry(fake_conn,
f00d0e
+                              DN('cn=%i,ou=certificateRepository' % i,
f00d0e
+                                 'ou=ca,o=ipaca'),
f00d0e
+                              userCertificate=[IPACertificate()],
f00d0e
+                              subjectName=[subject])
f00d0e
+            ldap_entries.append(entry)
f00d0e
+
f00d0e
+        mock_certdb.return_value = mock_CertDB(trust)
f00d0e
+
f00d0e
+        framework = object()
f00d0e
+        registry.initialize(framework, config.Config())
f00d0e
+        f = IPADogtagCertsMatchCheck(registry)
f00d0e
+        f.conn = mock_ldap(ldap_entries)
f00d0e
+        self.results = capture_results(f)
f00d0e
+
f00d0e
+        assert len(self.results) == 3
f00d0e
+        result = self.results.results[0]
f00d0e
+        assert result.result == constants.ERROR
f00d0e
+        assert result.source == 'ipahealthcheck.ipa.certs'
f00d0e
+        assert result.check == 'IPADogtagCertsMatchCheck'
f00d0e
-- 
f00d0e
2.26.3
f00d0e