URL: https://github.com/freeipa/freeipa/pull/4009 Author: tiran Title: #4009: [Backport][ipa-4-8] Check valid before/after of external certs Action: opened
PR body: """ This PR was opened automatically because PR #4004 was pushed to master and backport to ipa-4-8 is required. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/4009/head:pr4009 git checkout pr4009
From 0e89c02a6963708276c52447b5a24272aedfd52e Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Tue, 10 Dec 2019 12:46:14 +0100 Subject: [PATCH] Check valid before/after of external certs verify_server_cert_validity() and verify_ca_cert_validity() now check the validity time range of external certificates. The check fails if the certificate is not valid yet or will expire in less than an hour. Fixes: https://pagure.io/freeipa/issue/8142 Signed-off-by: Christian Heimes <chei...@redhat.com> --- ipapython/certdb.py | 22 ++++++++++++++++++++++ ipatests/test_ipapython/test_certdb.py | 13 +++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ipapython/certdb.py b/ipapython/certdb.py index 84ce1cf353..43245cd292 100644 --- a/ipapython/certdb.py +++ b/ipapython/certdb.py @@ -19,6 +19,7 @@ from __future__ import absolute_import import collections +import datetime import logging import os import io @@ -918,12 +919,32 @@ def delete_key_and_cert(self, nick): if certname == nick: self.delete_cert(nick) + def _verify_cert_validity(self, cert): + """Common checks for cert validity + """ + utcnow = datetime.datetime.utcnow() + if cert.not_valid_before > utcnow: + raise ValueError( + f"not valid before {cert.not_valid_before} UTC is in the " + "future." + ) + if cert.not_valid_after < utcnow: + raise ValueError( + f"has expired {cert.not_valid_after} UTC" + ) + # make sure the cert does not expire during installation + if cert.not_valid_after + datetime.timedelta(hours=1) < utcnow: + raise ValueError( + f"expires in less than one hour ({cert.not_valid_after} UTC)" + ) + def verify_server_cert_validity(self, nickname, hostname): """Verify a certificate is valid for a SSL server with given hostname Raises a ValueError if the certificate is invalid. """ cert = self.get_cert(nickname) + self._verify_cert_validity(cert) try: self.run_certutil( @@ -947,6 +968,7 @@ def verify_server_cert_validity(self, nickname, hostname): def verify_ca_cert_validity(self, nickname, minpathlen=None): cert = self.get_cert(nickname) + self._verify_cert_validity(cert) if not cert.subject: raise ValueError("has empty subject") diff --git a/ipatests/test_ipapython/test_certdb.py b/ipatests/test_ipapython/test_certdb.py index d6d1457764..e4366de6da 100644 --- a/ipatests/test_ipapython/test_certdb.py +++ b/ipatests/test_ipapython/test_certdb.py @@ -9,6 +9,7 @@ from ipaplatform.osinfo import osinfo CERTNICK = 'testcert' +CERTSAN = 'testcert.certdb.test' if osinfo.id == 'fedora': if osinfo.version_number >= (28,): @@ -33,6 +34,7 @@ def create_selfsigned(nssdb): '-s', 'CN=testcert', '-n', CERTNICK, '-m', '365', + '--extSAN', f'dns:{CERTSAN}' ]) finally: os.unlink(noisefile) @@ -242,3 +244,14 @@ def test_delete_cert_and_key(): assert len(nssdb.list_certs()) == 1 finally: os.unlink(p12file) + + +def test_check_validity(): + with NSSDatabase() as nssdb: + nssdb.create_db() + create_selfsigned(nssdb) + with pytest.raises(ValueError): + nssdb.verify_ca_cert_validity(CERTNICK) + nssdb.verify_server_cert_validity(CERTNICK, CERTSAN) + with pytest.raises(ValueError): + nssdb.verify_server_cert_validity(CERTNICK, 'invalid.example')
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org