Skip to content

Commit

Permalink
Add timezone-aware API variant for x509.InvalidityDate.invalidity_date
Browse files Browse the repository at this point in the history
  • Loading branch information
facutuesca committed Apr 18, 2024
1 parent 56cd2a2 commit 616cc73
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ Changelog
:attr:`~cryptography.x509.CertificateSigningRequest.public_key_algorithm_oid`
to determine the :class:`~cryptography.hazmat._oid.PublicKeyAlgorithmOID`
Object Identifier of the public key found inside the certificate.
* Added :attr:`~cryptography.x509.InvalidityDate.invalidity_date_utc`, a
timezone-aware alternative to the naïve ``datetime`` attribute
:attr:`~cryptography.x509.InvalidityDate.invalidity_date`.

.. _v42-0-5:

Expand Down
10 changes: 9 additions & 1 deletion docs/x509/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ X.509 Revoked Certificate Object

>>> for ext in revoked_certificate.extensions:
... print(ext)
<Extension(oid=<ObjectIdentifier(oid=2.5.29.24, name=invalidityDate)>, critical=False, value=<InvalidityDate(invalidity_date=2015-01-01 00:00:00)>)>
<Extension(oid=<ObjectIdentifier(oid=2.5.29.24, name=invalidityDate)>, critical=False, value=<InvalidityDate(invalidity_date=2015-01-01 00:00:00+00:00)>)>
<Extension(oid=<ObjectIdentifier(oid=2.5.29.21, name=cRLReason)>, critical=False, value=<CRLReason(reason=ReasonFlags.key_compromise)>)>

X.509 Revoked Certificate Builder
Expand Down Expand Up @@ -3148,6 +3148,14 @@ These extensions are only valid within a :class:`RevokedCertificate` object.

:type: :class:`datetime.datetime`

.. attribute:: invalidity_date_utc

.. versionadded:: 43.0.0

:type: :class:`datetime.datetime`

The invalidity date in UTC as a timezone-aware datetime object.

OCSP Extensions
~~~~~~~~~~~~~~~

Expand Down
9 changes: 8 additions & 1 deletion src/cryptography/x509/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,7 @@ def __init__(self, invalidity_date: datetime.datetime) -> None:
self._invalidity_date = invalidity_date

def __repr__(self) -> str:
return f"<InvalidityDate(invalidity_date={self._invalidity_date})>"
return f"<InvalidityDate(invalidity_date={self.invalidity_date})>"

def __eq__(self, other: object) -> bool:
if not isinstance(other, InvalidityDate):
Expand All @@ -1788,6 +1788,13 @@ def __hash__(self) -> int:
def invalidity_date(self) -> datetime.datetime:
return self._invalidity_date

@property
def invalidity_date_utc(self) -> datetime.datetime:
if self._invalidity_date.tzinfo is None:
return self._invalidity_date.replace(tzinfo=datetime.timezone.utc)
else:
return self._invalidity_date.astimezone(tz=datetime.timezone.utc)

def public_bytes(self) -> bytes:
return rust_x509.encode_extension_value(self)

Expand Down
2 changes: 1 addition & 1 deletion src/rust/src/x509/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ pub(crate) fn encode_extension(
Ok(Some(asn1::write_single(&asn1::SequenceOfWriter::new(gns))?))
}
&oid::INVALIDITY_DATE_OID => {
let py_dt = ext.getattr(pyo3::intern!(py, "invalidity_date"))?;
let py_dt = ext.getattr(pyo3::intern!(py, "invalidity_date_utc"))?;
let dt = x509::py_to_datetime(py, py_dt)?;
Ok(Some(asn1::write_single(&asn1::GeneralizedTime::new(dt)?)?))
}
Expand Down
20 changes: 20 additions & 0 deletions tests/x509/test_x509_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,26 @@ def test_public_bytes(self):
ext = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 1))
assert ext.public_bytes() == b"\x18\x0f20150101010100Z"

def test_timezone_aware_api(self):
naive_date = datetime.datetime(2015, 1, 1, 1, 1)
ext_naive = x509.InvalidityDate(invalidity_date=naive_date)
assert ext_naive.invalidity_date_utc == datetime.datetime(
2015, 1, 1, 1, 1, tzinfo=datetime.timezone.utc
)

tz_aware_date = datetime.datetime(
2015,
1,
1,
1,
1,
tzinfo=datetime.timezone(datetime.timedelta(hours=-8)),
)
ext_aware = x509.InvalidityDate(invalidity_date=tz_aware_date)
assert ext_aware.invalidity_date_utc == datetime.datetime(
2015, 1, 1, 9, 1, tzinfo=datetime.timezone.utc
)


class TestNoticeReference:
def test_notice_numbers_not_all_int(self):
Expand Down

0 comments on commit 616cc73

Please sign in to comment.