diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 141c256f1..ae7a1a90c 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -15,7 +15,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Fixed -* +* Removed a CryptographyDeprecationWarning that was being displayed to users + when checking OCSP status. More details about these changes can be found on our GitHub repo. diff --git a/certbot/certbot/_internal/tests/ocsp_test.py b/certbot/certbot/_internal/tests/ocsp_test.py index 86abf8bf4..20034e012 100644 --- a/certbot/certbot/_internal/tests/ocsp_test.py +++ b/certbot/certbot/_internal/tests/ocsp_test.py @@ -6,12 +6,14 @@ from datetime import timedelta import sys import unittest from unittest import mock +import warnings from cryptography import x509 from cryptography.exceptions import InvalidSignature from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes +from cryptography.utils import CryptographyDeprecationWarning from cryptography.x509 import ocsp as ocsp_lib import pytest import pytz @@ -284,6 +286,25 @@ class OSCPTestCryptography(unittest.TestCase): revoked = self.checker.ocsp_revoked(self.cert_obj) assert revoked is False + def test_this_update_warning(self): + with _ocsp_mock(ocsp_lib.OCSPCertStatus.GOOD, + ocsp_lib.OCSPResponseStatus.SUCCESSFUL) as mocks: + value = mocks['mock_response'].return_value.this_update + + def warn_first(): + msg = ('Properties that return a naïve datetime object have been deprecated. Please ' + 'switch to this_update_utc.') + warnings.warn(msg, CryptographyDeprecationWarning) + return value + + property_mock = mock.PropertyMock(side_effect=warn_first) + # Using type() in this way is recommended in mock's documentation at + # https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock + type(mocks['mock_response'].return_value).this_update = property_mock + + revoked = self.checker.ocsp_revoked(self.cert_obj) + assert revoked is False + @contextlib.contextmanager def _ocsp_mock(certificate_status, response_status, diff --git a/certbot/certbot/ocsp.py b/certbot/certbot/ocsp.py index a24f04f0d..82937c7ea 100644 --- a/certbot/certbot/ocsp.py +++ b/certbot/certbot/ocsp.py @@ -7,6 +7,7 @@ import subprocess from subprocess import PIPE from typing import Optional from typing import Tuple +import warnings from cryptography import x509 from cryptography.exceptions import InvalidSignature @@ -235,12 +236,17 @@ def _check_ocsp_response(response_ocsp: 'ocsp.OCSPResponse', request_ocsp: 'ocsp # https://github.com/openssl/openssl/blob/ef45aa14c5af024fcb8bef1c9007f3d1c115bd85/crypto/ocsp/ocsp_cl.c#L338-L391 # thisUpdate/nextUpdate are expressed in UTC/GMT time zone now = datetime.now(pytz.UTC).replace(tzinfo=None) - if not response_ocsp.this_update: - raise AssertionError('param thisUpdate is not set.') - if response_ocsp.this_update > now + timedelta(minutes=5): - raise AssertionError('param thisUpdate is in the future.') - if response_ocsp.next_update and response_ocsp.next_update < now - timedelta(minutes=5): - raise AssertionError('param nextUpdate is in the past.') + # The this_update and next_update attributes were deprecated in cryptography's 43.0.0 release. + # Updating the code and tests to (also) work with the new API is being tracked in + # https://github.com/certbot/certbot/issues/10053. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', message='Properties that return.*datetime object') + if not response_ocsp.this_update: + raise AssertionError('param thisUpdate is not set.') + if response_ocsp.this_update > now + timedelta(minutes=5): + raise AssertionError('param thisUpdate is in the future.') + if response_ocsp.next_update and response_ocsp.next_update < now - timedelta(minutes=5): + raise AssertionError('param nextUpdate is in the past.') def _check_ocsp_response_signature(response_ocsp: 'ocsp.OCSPResponse',