Skip to content

Commit da2465f

Browse files
authored
PYTHON-4611 Prefer non deprecated cryptography apis (mongodb#1770)
1 parent a5d5197 commit da2465f

File tree

2 files changed

+50
-21
lines changed

2 files changed

+50
-21
lines changed

pymongo/ocsp_cache.py

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,30 @@
1919
from collections import namedtuple
2020
from datetime import datetime as _datetime
2121
from datetime import timezone
22-
from typing import TYPE_CHECKING, Any
22+
from typing import TYPE_CHECKING, Any, Optional
2323

2424
from pymongo.lock import _create_lock
2525

2626
if TYPE_CHECKING:
2727
from cryptography.x509.ocsp import OCSPRequest, OCSPResponse
2828

2929

30+
def _next_update(value: OCSPResponse) -> Optional[_datetime]:
31+
"""Compat helper to return the response's next_update_utc."""
32+
# Added in cryptography 43.0.0.
33+
if hasattr(value, "next_update_utc"):
34+
return value.next_update_utc
35+
return value.next_update
36+
37+
38+
def _this_update(value: OCSPResponse) -> Optional[_datetime]:
39+
"""Compat helper to return the response's this_update_utc."""
40+
# Added in cryptography 43.0.0.
41+
if hasattr(value, "this_update_utc"):
42+
return value.this_update_utc
43+
return value.this_update
44+
45+
3046
class _OCSPCache:
3147
"""A cache for OCSP responses."""
3248

@@ -62,25 +78,30 @@ def __setitem__(self, key: OCSPRequest, value: OCSPResponse) -> None:
6278
# As per the OCSP protocol, if the response's nextUpdate field is
6379
# not set, the responder is indicating that newer revocation
6480
# information is available all the time.
65-
if value.next_update is None:
81+
next_update = _next_update(value)
82+
if next_update is None:
6683
self._data.pop(cache_key, None)
6784
return
6885

86+
this_update = _this_update(value)
87+
if this_update is None:
88+
return
89+
now = _datetime.now(tz=timezone.utc)
90+
if this_update.tzinfo is None:
91+
# Make naive to match cryptography.
92+
now = now.replace(tzinfo=None)
6993
# Do nothing if the response is invalid.
70-
if not (
71-
value.this_update
72-
<= _datetime.now(tz=timezone.utc).replace(tzinfo=None)
73-
< value.next_update
74-
):
94+
if not (this_update <= now < next_update):
7595
return
7696

7797
# Cache new response OR update cached response if new response
7898
# has longer validity.
7999
cached_value = self._data.get(cache_key, None)
80-
if cached_value is None or (
81-
cached_value.next_update is not None
82-
and cached_value.next_update < value.next_update
83-
):
100+
if cached_value is None:
101+
self._data[cache_key] = value
102+
return
103+
cached_next_update = _next_update(cached_value)
104+
if cached_next_update is not None and cached_next_update < next_update:
84105
self._data[cache_key] = value
85106

86107
def __getitem__(self, item: OCSPRequest) -> OCSPResponse:
@@ -95,13 +116,15 @@ def __getitem__(self, item: OCSPRequest) -> OCSPResponse:
95116
value = self._data[cache_key]
96117

97118
# Return cached response if it is still valid.
98-
assert value.this_update is not None
99-
assert value.next_update is not None
100-
if (
101-
value.this_update
102-
<= _datetime.now(tz=timezone.utc).replace(tzinfo=None)
103-
< value.next_update
104-
):
119+
this_update = _this_update(value)
120+
next_update = _next_update(value)
121+
assert this_update is not None
122+
assert next_update is not None
123+
now = _datetime.now(tz=timezone.utc)
124+
if this_update.tzinfo is None:
125+
# Make naive to match cryptography.
126+
now = now.replace(tzinfo=None)
127+
if this_update <= now < next_update:
105128
return value
106129

107130
self._data.pop(cache_key, None)

pymongo/ocsp_support.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from requests.exceptions import RequestException as _RequestException
5959

6060
from pymongo import _csot
61+
from pymongo.ocsp_cache import _next_update, _this_update
6162

6263
if TYPE_CHECKING:
6364
from cryptography.hazmat.primitives.asymmetric import (
@@ -275,13 +276,18 @@ def _verify_response(issuer: Certificate, response: OCSPResponse) -> int:
275276

276277
# Note that we are not using a "tolerance period" as discussed in
277278
# https://tools.ietf.org/rfc/rfc5019.txt?
278-
now = _datetime.now(tz=timezone.utc).replace(tzinfo=None)
279+
this_update = _this_update(response)
280+
now = _datetime.now(tz=timezone.utc)
281+
if this_update and this_update.tzinfo is None:
282+
# Make naive to match cryptography.
283+
now = now.replace(tzinfo=None)
279284
# RFC6960, Section 3.2, Number 5
280-
if response.this_update > now:
285+
if this_update and this_update > now:
281286
_LOGGER.debug("thisUpdate is in the future")
282287
return 0
283288
# RFC6960, Section 3.2, Number 6
284-
if response.next_update and response.next_update < now:
289+
next_update = _next_update(response)
290+
if next_update and next_update < now:
285291
_LOGGER.debug("nextUpdate is in the past")
286292
return 0
287293
return 1

0 commit comments

Comments
 (0)