Skip to content

Commit d2f0aec

Browse files
davidbenalex
andauthored
Fix CRL nextUpdate handling. (#1169)
* Fix CRL nextUpdate handling. When setting the nextUpdate field of a CRL, this code grabbed the nextUpdate ASN1_TIME field from the CRL and set its time. But nextUpdate is optional in a CRL so that field is usually NULL. But OpenSSL's ASN1_TIME_set_string succeeds when the destination argument is NULL, so it was silently a no-op. Given that, the call in a test to set the nextUpdate field suddenly starts working and sets the time to 2018, thus causing the CRL to be considered expired and breaking the test. So this change also changes the expiry year far into the future. Additionally, the other CRL and Revoked setters violate const in the API. Fixes #1168. * Replace self-check with an assert for coverage * Update src/OpenSSL/crypto.py Co-authored-by: Alex Gaynor <[email protected]> Co-authored-by: Alex Gaynor <[email protected]>
1 parent 4aae795 commit d2f0aec

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

src/OpenSSL/crypto.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,34 @@ def _set_asn1_time(boundary: Any, when: bytes) -> None:
168168
"""
169169
if not isinstance(when, bytes):
170170
raise TypeError("when must be a byte string")
171+
# ASN1_TIME_set_string validates the string without writing anything
172+
# when the destination is NULL.
173+
_openssl_assert(boundary != _ffi.NULL)
171174

172175
set_result = _lib.ASN1_TIME_set_string(boundary, when)
173176
if set_result == 0:
174177
raise ValueError("Invalid string")
175178

176179

180+
def _new_asn1_time(when: bytes) -> Any:
181+
"""
182+
Behaves like _set_asn1_time but returns a new ASN1_TIME object.
183+
184+
@param when: A string representation of the desired time value.
185+
186+
@raise TypeError: If C{when} is not a L{bytes} string.
187+
@raise ValueError: If C{when} does not represent a time in the required
188+
format.
189+
@raise RuntimeError: If the time value cannot be set for some other
190+
(unspecified) reason.
191+
"""
192+
ret = _lib.ASN1_TIME_new()
193+
_openssl_assert(ret != _ffi.NULL)
194+
ret = _ffi.gc(ret, _lib.ASN1_TIME_free)
195+
_set_asn1_time(ret, when)
196+
return ret
197+
198+
177199
def _get_asn1_time(timestamp: Any) -> Optional[bytes]:
178200
"""
179201
Retrieve the time value of an ASN1 time object.
@@ -2283,8 +2305,11 @@ def set_rev_date(self, when: bytes) -> None:
22832305
as ASN.1 TIME.
22842306
:return: ``None``
22852307
"""
2286-
dt = _lib.X509_REVOKED_get0_revocationDate(self._revoked)
2287-
return _set_asn1_time(dt, when)
2308+
revocationDate = _new_asn1_time(when)
2309+
ret = _lib.X509_REVOKED_set_revocationDate(
2310+
self._revoked, revocationDate
2311+
)
2312+
_openssl_assert(ret == 1)
22882313

22892314
def get_rev_date(self) -> Optional[bytes]:
22902315
"""
@@ -2406,11 +2431,6 @@ def set_version(self, version: int) -> None:
24062431
"""
24072432
_openssl_assert(_lib.X509_CRL_set_version(self._crl, version) != 0)
24082433

2409-
def _set_boundary_time(
2410-
self, which: Callable[..., Any], when: bytes
2411-
) -> None:
2412-
return _set_asn1_time(which(self._crl), when)
2413-
24142434
def set_lastUpdate(self, when: bytes) -> None:
24152435
"""
24162436
Set when the CRL was last updated.
@@ -2424,7 +2444,9 @@ def set_lastUpdate(self, when: bytes) -> None:
24242444
:param bytes when: A timestamp string.
24252445
:return: ``None``
24262446
"""
2427-
return self._set_boundary_time(_lib.X509_CRL_get0_lastUpdate, when)
2447+
lastUpdate = _new_asn1_time(when)
2448+
ret = _lib.X509_CRL_set1_lastUpdate(self._crl, lastUpdate)
2449+
_openssl_assert(ret == 1)
24282450

24292451
def set_nextUpdate(self, when: bytes) -> None:
24302452
"""
@@ -2439,7 +2461,9 @@ def set_nextUpdate(self, when: bytes) -> None:
24392461
:param bytes when: A timestamp string.
24402462
:return: ``None``
24412463
"""
2442-
return self._set_boundary_time(_lib.X509_CRL_get0_nextUpdate, when)
2464+
nextUpdate = _new_asn1_time(when)
2465+
ret = _lib.X509_CRL_set1_nextUpdate(self._crl, nextUpdate)
2466+
_openssl_assert(ret == 1)
24432467

24442468
def sign(self, issuer_cert: X509, issuer_key: PKey, digest: bytes) -> None:
24452469
"""

tests/test_crypto.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3850,7 +3850,9 @@ def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
38503850
crl.add_revoked(revoked)
38513851
crl.set_version(1)
38523852
crl.set_lastUpdate(b"20140601000000Z")
3853-
crl.set_nextUpdate(b"20180601000000Z")
3853+
# The year 5000 is far into the future so that this CRL isn't
3854+
# considered to have expired.
3855+
crl.set_nextUpdate(b"50000601000000Z")
38543856
crl.sign(issuer_cert, issuer_key, digest=b"sha512")
38553857
return crl
38563858

0 commit comments

Comments
 (0)