Skip to content

Commit

Permalink
Use timezone aware comparisons for cert validity (#50)
Browse files Browse the repository at this point in the history
* Use timezone aware comparisons for cert validity

* Ran format

* Switch to backward compatible timezone.utc

* make format

---------

Co-authored-by: Alex Cottner <[email protected]>
  • Loading branch information
leplatrem and alexcottner authored Sep 18, 2024
1 parent 0f14801 commit 4000db2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 18 deletions.
14 changes: 7 additions & 7 deletions src/autograph_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,15 +332,15 @@ async def verify_x5u(self, url):

now = _now()
for cert in certs:
if cert.not_valid_before > cert.not_valid_after:
if cert.not_valid_before_utc > cert.not_valid_after_utc:
raise BadCertificate(
f"not_before ({cert.not_valid_before}) after "
f"not_after ({cert.not_valid_after})"
f"not_before ({cert.not_valid_before_utc}) after "
f"not_after ({cert.not_valid_after_utc})"
)
if now < cert.not_valid_before:
raise CertificateNotYetValid(cert.not_valid_before)
if now > cert.not_valid_after:
raise CertificateExpired(cert.not_valid_after)
if now < cert.not_valid_before_utc:
raise CertificateNotYetValid(cert.not_valid_before_utc)
if now > cert.not_valid_after_utc:
raise CertificateExpired(cert.not_valid_after_utc)

# Verify chain of trust.
chain = certs[::-1]
Expand Down
23 changes: 12 additions & 11 deletions tests/test_autograph_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import datetime
import os.path
from datetime import timezone
from unittest import mock

import aiohttp
Expand Down Expand Up @@ -89,7 +90,7 @@ def cache():
def now_fixed():
with mock.patch("autograph_utils._now") as m:
# A common static time used in a lot of tests.
m.return_value = datetime.datetime(2019, 10, 23, 16, 16)
m.return_value = datetime.datetime(2019, 10, 23, 16, 16, tzinfo=timezone.utc)
# Yield the mock so someone can change the time if they want
yield m

Expand All @@ -107,8 +108,8 @@ def mock_cert(real_cert):
"""

mock_cert = mock.MagicMock(wraps=real_cert)
mock_cert.not_valid_before = real_cert.not_valid_before
mock_cert.not_valid_after = real_cert.not_valid_after
mock_cert.not_valid_before_utc = real_cert.not_valid_before_utc
mock_cert.not_valid_after_utc = real_cert.not_valid_after_utc
mock_cert.signature = real_cert.signature
mock_cert.tbs_certificate_bytes = real_cert.tbs_certificate_bytes
mock_cert.signature_hash_algorithm = real_cert.signature_hash_algorithm
Expand Down Expand Up @@ -180,21 +181,21 @@ async def test_verify_signature_bad_numbers(aiohttp_session, mock_with_x5u, cach


async def test_verify_x5u_expired(aiohttp_session, mock_with_x5u, cache, now_fixed):
now_fixed.return_value = datetime.datetime(2022, 10, 23, 16, 16, 16)
now_fixed.return_value = datetime.datetime(2022, 10, 23, 16, 16, 16, tzinfo=timezone.utc)
s = SignatureVerifier(aiohttp_session, cache, DEV_ROOT_HASH)
with pytest.raises(autograph_utils.CertificateExpired) as excinfo:
await s.verify(SIGNED_DATA, SAMPLE_SIGNATURE, FAKE_CERT_URL)

assert excinfo.value.detail == "Certificate expired on 2021-07-05 21:57:15"
assert excinfo.value.detail == "Certificate expired on 2021-07-05 21:57:15+00:00"


async def test_verify_x5u_too_soon(aiohttp_session, mock_with_x5u, cache, now_fixed):
now_fixed.return_value = datetime.datetime(2010, 10, 23, 16, 16, 16)
now_fixed.return_value = datetime.datetime(2010, 10, 23, 16, 16, 16, tzinfo=timezone.utc)
s = SignatureVerifier(aiohttp_session, cache, DEV_ROOT_HASH)
with pytest.raises(autograph_utils.CertificateNotYetValid) as excinfo:
await s.verify(SIGNED_DATA, SAMPLE_SIGNATURE, FAKE_CERT_URL)

assert excinfo.value.detail == "Certificate is not valid until 2016-07-06 21:57:15"
assert excinfo.value.detail == "Certificate is not valid until 2016-07-06 21:57:15+00:00"


async def test_verify_x5u_screwy_dates(aiohttp_session, mock_with_x5u, cache, now_fixed):
Expand All @@ -204,16 +205,16 @@ async def test_verify_x5u_screwy_dates(aiohttp_session, mock_with_x5u, cache, no
CERT_LIST[0], backend=default_backend()
)
bad_cert = mock_cert(leaf_cert)
bad_cert.not_valid_before = leaf_cert.not_valid_after
bad_cert.not_valid_after = leaf_cert.not_valid_before
bad_cert.not_valid_before_utc = leaf_cert.not_valid_after_utc
bad_cert.not_valid_after_utc = leaf_cert.not_valid_before_utc
with mock.patch("autograph_utils.x509.load_pem_x509_certificate") as x509:
x509.return_value = bad_cert
with pytest.raises(autograph_utils.BadCertificate) as excinfo:
await s.verify(SIGNED_DATA, SAMPLE_SIGNATURE, FAKE_CERT_URL)

assert excinfo.value.detail == (
"Bad certificate: not_before (2021-07-05 21:57:15) "
"after not_after (2016-07-06 21:57:15)"
"Bad certificate: not_before (2021-07-05 21:57:15+00:00) "
"after not_after (2016-07-06 21:57:15+00:00)"
)


Expand Down

0 comments on commit 4000db2

Please sign in to comment.