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

Reply via email to