def ocsp_revoked(self, version): """Is the specified cert version revoked according to OCSP? Also returns True if the cert version is declared as revoked according to OCSP. If OCSP status could not be determined, False is returned. :param int version: the desired version number :returns: True if the certificate is revoked, otherwise, False :rtype: bool """ cert_path = self.version("cert", version) chain_path = self.version("chain", version) # While the RevocationChecker should return False if it failed to # determine the OCSP status, let's ensure we don't crash Certbot by # catching all exceptions here. try: return ocsp.RevocationChecker().ocsp_revoked_by_paths( cert_path, chain_path) except Exception as e: # pylint: disable=broad-except logger.warning( "An error occurred determining the OCSP status of %s.", cert_path) logger.debug(str(e)) return False
def setUp(self): from certbot import ocsp with mock.patch('certbot.ocsp.subprocess.run') as mock_run: with mock.patch('certbot.util.exe_exists') as mock_exists: mock_run.stderr = out mock_exists.return_value = True self.checker = ocsp.RevocationChecker( enforce_openssl_binary_usage=True)
def setUp(self): from certbot import ocsp with mock.patch('certbot.ocsp.Popen') as mock_popen: with mock.patch('certbot.util.exe_exists') as mock_exists: mock_communicate = mock.MagicMock() mock_communicate.communicate.return_value = (None, out) mock_popen.return_value = mock_communicate mock_exists.return_value = True self.checker = ocsp.RevocationChecker()
def setUp(self): from certbot import ocsp self.checker = ocsp.RevocationChecker() self.cert_path = test_util.vector_path('ocsp_certificate.pem') self.chain_path = test_util.vector_path('ocsp_issuer_certificate.pem') self.cert_obj = mock.MagicMock() self.cert_obj.cert = self.cert_path self.cert_obj.chain = self.chain_path now = pytz.UTC.fromutc(datetime.utcnow()) self.cert_obj.target_expiry = now + timedelta(hours=2)
def test_init(self, mock_exists, mock_run, mock_log): mock_run.return_value.stderr = out mock_exists.return_value = True from certbot import ocsp checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True) self.assertEqual(mock_run.call_count, 1) self.assertEqual(checker.host_args("x"), ["Host=x"]) mock_run.return_value.stderr = out.partition("\n")[2] checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True) self.assertEqual(checker.host_args("x"), ["Host", "x"]) self.assertIs(checker.broken, False) mock_exists.return_value = False mock_run.call_count = 0 checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True) self.assertEqual(mock_run.call_count, 0) self.assertEqual(mock_log.call_count, 1) self.assertIs(checker.broken, True)
def test_init(self, mock_exists, mock_popen, mock_log): mock_communicate = mock.MagicMock() mock_communicate.communicate.return_value = (None, out) mock_popen.return_value = mock_communicate mock_exists.return_value = True from certbot import ocsp checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True) self.assertEqual(mock_popen.call_count, 1) self.assertEqual(checker.host_args("x"), ["Host=x"]) mock_communicate.communicate.return_value = (None, out.partition("\n")[2]) checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True) self.assertEqual(checker.host_args("x"), ["Host", "x"]) self.assertEqual(checker.broken, False) mock_exists.return_value = False mock_popen.call_count = 0 checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True) self.assertEqual(mock_popen.call_count, 0) self.assertEqual(mock_log.call_count, 1) self.assertEqual(checker.broken, True)
def setUp(self): from certbot import ocsp self.checker = ocsp.RevocationChecker() self.cert_path = test_util.vector_path('ocsp_certificate.pem') self.chain_path = test_util.vector_path('ocsp_issuer_certificate.pem') self.cert_obj = mock.MagicMock() self.cert_obj.cert_path = self.cert_path self.cert_obj.chain_path = self.chain_path now = pytz.UTC.fromutc(datetime.utcnow()) self.mock_notAfter = mock.patch('certbot.ocsp.crypto_util.notAfter', return_value=now + timedelta(hours=2)) self.mock_notAfter.start() # Ensure the mock.patch is stopped even if test raises an exception self.addCleanup(self.mock_notAfter.stop)
def human_readable_cert_info( config: configuration.NamespaceConfig, cert: storage.RenewableCert, skip_filter_checks: bool = False) -> Optional[str]: """ Returns a human readable description of info about a RenewableCert object""" certinfo = [] checker = ocsp.RevocationChecker() if config.certname and cert.lineagename != config.certname and not skip_filter_checks: return None if config.domains and not set(config.domains).issubset(cert.names()): return None now = pytz.UTC.fromutc(datetime.datetime.utcnow()) reasons = [] if cert.is_test_cert: reasons.append('TEST_CERT') if cert.target_expiry <= now: reasons.append('EXPIRED') elif checker.ocsp_revoked(cert): reasons.append('REVOKED') if reasons: status = "INVALID: " + ", ".join(reasons) else: diff = cert.target_expiry - now if diff.days == 1: status = "VALID: 1 day" elif diff.days < 1: status = "VALID: {0} hour(s)".format(diff.seconds // 3600) else: status = "VALID: {0} days".format(diff.days) valid_string = "{0} ({1})".format(cert.target_expiry, status) serial = format(crypto_util.get_serial_from_cert(cert.cert_path), 'x') certinfo.append(" Certificate Name: {}\n" " Serial Number: {}\n" " Key Type: {}\n" " Domains: {}\n" " Expiry Date: {}\n" " Certificate Path: {}\n" " Private Key Path: {}".format(cert.lineagename, serial, cert.private_key_type, " ".join(cert.names()), valid_string, cert.fullchain, cert.privkey)) return "".join(certinfo)
def _report_human_readable(config, parsed_certs): """Format a results report for a parsed cert""" certinfo = [] checker = ocsp.RevocationChecker() for cert in parsed_certs: if config.certname and cert.lineagename != config.certname: continue if config.domains and not set(config.domains).issubset(cert.names()): continue now = pytz.UTC.fromutc(datetime.datetime.utcnow()) reasons = [] if cert.is_test_cert: reasons.append('TEST_CERT') if cert.target_expiry <= now: reasons.append('EXPIRED') if checker.ocsp_revoked(cert.cert, cert.chain): reasons.append('REVOKED') if reasons: status = "INVALID: " + ", ".join(reasons) else: diff = cert.target_expiry - now if diff.days == 1: status = "VALID: 1 day" elif diff.days < 1: status = "VALID: {0} hour(s)".format(diff.seconds // 3600) else: status = "VALID: {0} days".format(diff.days) valid_string = "{0} ({1})".format(cert.target_expiry, status) certinfo.append(" Certificate Name: {0}\n" " Domains: {1}\n" " Expiry Date: {2}\n" " Certificate Path: {3}\n" " Private Key Path: {4}".format( cert.lineagename, " ".join(cert.names()), valid_string, cert.fullchain, cert.privkey)) return "\n".join(certinfo)
def human_readable_cert_info(config, cert, skip_filter_checks=False): """ Returns a human readable description of info about a RenewableCert object""" certinfo = [] checker = ocsp.RevocationChecker() if config.certname and cert.lineagename != config.certname and not skip_filter_checks: return "" if config.domains and not set(config.domains).issubset(cert.names()): return "" now = pytz.UTC.fromutc(datetime.datetime.utcnow()) reasons = [] if cert.is_test_cert: reasons.append('TEST_CERT') if cert.target_expiry <= now: reasons.append('EXPIRED') if checker.ocsp_revoked(cert.cert, cert.chain): reasons.append('REVOKED') if reasons: status = "INVALID: " + ", ".join(reasons) else: diff = cert.target_expiry - now if diff.days == 1: status = "VALID: 1 day" elif diff.days < 1: status = "VALID: {0} hour(s)".format(diff.seconds // 3600) else: status = "VALID: {0} days".format(diff.days) valid_string = "{0} ({1})".format(cert.target_expiry, status) certinfo.append(" Certificate Name: {0}\n" " Domains: {1}\n" " Expiry Date: {2}\n" " Certificate Path: {3}\n" " Private Key Path: {4}".format( cert.lineagename, " ".join(cert.names()), valid_string, cert.fullchain, cert.privkey)) return "".join(certinfo)
def setUp(self): from certbot import ocsp self.checker = ocsp.RevocationChecker() self.cert_path = test_util.vector_path('google_certificate.pem') self.chain_path = test_util.vector_path('google_issuer_certificate.pem')