repin cryptography for openssl security update (#9565)

* repin cryptography for openssl security update

https://www.openssl.org/news/secadv/20230207.txt
https://cryptography.io/en/latest/changelog/#v39-0-1

* fix type hints

* remove outdated comments
This commit is contained in:
alexzorin 2023-02-09 06:17:44 +11:00 committed by GitHub
parent 23090198bf
commit 99184daff6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 78 deletions

View file

@ -22,13 +22,13 @@ SYSTEM_SID = 'S-1-5-18'
ADMINS_SID = 'S-1-5-32-544'
def assert_elliptic_key(key: str, curve: Type[EllipticCurve]) -> None:
def assert_elliptic_key(key_path: str, curve: Type[EllipticCurve]) -> None:
"""
Asserts that the key at the given path is an EC key using the given curve.
:param key: path to key
:param key_path: path to key
:param EllipticCurve curve: name of the expected elliptic curve
"""
with open(key, 'rb') as file:
with open(key_path, 'rb') as file:
privkey1 = file.read()
key = load_pem_private_key(data=privkey1, password=None, backend=default_backend())
@ -37,13 +37,13 @@ def assert_elliptic_key(key: str, curve: Type[EllipticCurve]) -> None:
assert isinstance(key.curve, curve), f"should have curve {curve} but was {key.curve}"
def assert_rsa_key(key: str, key_size: Optional[int] = None) -> None:
def assert_rsa_key(key_path: str, key_size: Optional[int] = None) -> None:
"""
Asserts that the key at the given path is an RSA key.
:param str key: path to key
:param str key_path: path to key
:param int key_size: if provided, assert that the RSA key is of this size
"""
with open(key, 'rb') as file:
with open(key_path, 'rb') as file:
privkey1 = file.read()
key = load_pem_private_key(data=privkey1, password=None, backend=default_backend())

View file

@ -916,7 +916,7 @@ def test_preferred_chain(context: IntegrationTestsContext) -> None:
except NotImplementedError:
pytest.skip('This ACME server does not support alternative issuers.')
names = [i.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value \
names = [str(i.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value) \
for i in issuers]
domain = context.get_domain('preferred-chain')
@ -929,9 +929,9 @@ def test_preferred_chain(context: IntegrationTestsContext) -> None:
context.certbot(args)
dumped = misc.read_certificate(cert_path)
assert 'Issuer: CN={}'.format(expected) in dumped, \
'Expected chain issuer to be {} when preferring {}'.format(expected, requested)
assert f'Issuer: CN={expected}'in dumped, \
f'Expected chain issuer to be {expected} when preferring {requested}'
with open(conf_path, 'r') as f:
assert 'preferred_chain = {}'.format(requested) in f.read(), \
assert f'preferred_chain = {requested}' in f.read(), \
'Expected preferred_chain to be set in renewal config'

View file

@ -230,11 +230,7 @@ def generate_csr(domains: Iterable[str], key_path: str, csr_path: str,
# Ignore a warning on some old versions of cryptography
warnings.simplefilter('ignore', category=PendingDeprecationWarning)
_key = ec.generate_private_key(ec.SECP384R1(), default_backend())
# This type ignore directive is required due to an outdated version of types-cryptography.
# It can be removed once package types-pyOpenSSL depends on cryptography instead of
# types-cryptography and so types-cryptography is not installed anymore.
# See https://github.com/python/typeshed/issues/5618
_bytes = _key.private_bytes(encoding=Encoding.PEM, # type: ignore
_bytes = _key.private_bytes(encoding=Encoding.PEM,
format=PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=NoEncryption())
key = crypto.load_privatekey(crypto.FILETYPE_PEM, _bytes)

View file

@ -11,9 +11,13 @@ from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.x509 import ocsp
from dateutil import parser
import requests
from typing import cast
from typing import Union
from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT
from certbot_integration_tests.utils.constants import PEBBLE_MANAGEMENT_URL
@ -25,7 +29,9 @@ class _ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self) -> None:
request = requests.get(PEBBLE_MANAGEMENT_URL + '/intermediate-keys/0',
verify=False, timeout=10)
issuer_key = serialization.load_pem_private_key(request.content, None, default_backend())
issuer_key = cast(
Union[RSAPrivateKey, EllipticCurvePrivateKey],
serialization.load_pem_private_key(request.content, None, default_backend()))
request = requests.get(PEBBLE_MANAGEMENT_URL + '/intermediates/0',
verify=False, timeout=10)

View file

@ -138,7 +138,7 @@ class _RFC2136Client:
except Exception as e:
raise errors.PluginError('Encountered error adding TXT record: {0}'
.format(e))
rcode = response.rcode() # type: ignore[attr-defined]
rcode = response.rcode()
if rcode == dns.rcode.NOERROR:
logger.debug('Successfully added TXT record %s', record_name)
@ -173,7 +173,7 @@ class _RFC2136Client:
except Exception as e:
raise errors.PluginError('Encountered error deleting TXT record: {0}'
.format(e))
rcode = response.rcode() # type: ignore[attr-defined]
rcode = response.rcode()
if rcode == dns.rcode.NOERROR:
logger.debug('Successfully deleted TXT record %s', record_name)
@ -217,7 +217,7 @@ class _RFC2136Client:
# Turn off Recursion Desired bit in query
request.flags ^= dns.flags.RD
# Use our TSIG keyring
request.use_tsig(self.keyring, algorithm=self.algorithm) # type: ignore[attr-defined]
request.use_tsig(self.keyring, algorithm=self.algorithm)
try:
try:
@ -225,11 +225,11 @@ class _RFC2136Client:
except (OSError, dns.exception.Timeout) as e:
logger.debug('TCP query failed, fallback to UDP: %s', e)
response = dns.query.udp(request, self.server, self._default_timeout, self.port)
rcode = response.rcode() # type: ignore[attr-defined]
rcode = response.rcode()
# Authoritative Answer bit should be set
if (rcode == dns.rcode.NOERROR
and response.get_rrset(response.answer, # type: ignore[attr-defined]
and response.get_rrset(response.answer,
domain, dns.rdataclass.IN, dns.rdatatype.SOA)
and response.flags & dns.flags.AA):
logger.debug('Received authoritative SOA response for %s', domain_name)

View file

@ -7,6 +7,7 @@ import re
import shutil
import stat
from typing import Any
from typing import cast
from typing import Dict
from typing import Iterable
from typing import List
@ -1133,7 +1134,7 @@ class RenewableCert(interfaces.RenewableCert):
password=None,
backend=default_backend()
)
return key
return cast(Union[RSAPrivateKey, EllipticCurvePrivateKey], key)
@property
def private_key_type(self) -> str:

View file

@ -45,6 +45,8 @@ from certbot.compat import os
if TYPE_CHECKING:
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PublicKey
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.hazmat.primitives.asymmetric.x448 import X448PublicKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PublicKey
logger = logging.getLogger(__name__)
@ -243,11 +245,7 @@ def make_key(bits: int = 1024, key_type: str = "rsa",
raise errors.Error("Unsupported elliptic curve: {}".format(elliptic_curve))
except UnsupportedAlgorithm as e:
raise e from errors.Error(str(e))
# This type ignore directive is required due to an outdated version of types-cryptography.
# It can be removed once package types-pyOpenSSL depends on cryptography instead of
# types-cryptography and so types-cryptography is not installed anymore.
# See https://github.com/python/typeshed/issues/5618
_key_pem = _key.private_bytes( # type: ignore
_key_pem = _key.private_bytes(
encoding=Encoding.PEM,
format=PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=NoEncryption()
@ -306,6 +304,7 @@ def verify_renewable_cert_sig(renewable_cert: interfaces.RenewableCert) -> None:
with open(renewable_cert.cert_path, 'rb') as cert_file:
cert = x509.load_pem_x509_certificate(cert_file.read(), default_backend())
pk = chain.public_key()
assert cert.signature_hash_algorithm # always present for RSA and ECDSA
verify_signed_payload(pk, cert.signature, cert.tbs_certificate_bytes,
cert.signature_hash_algorithm)
except (IOError, ValueError, InvalidSignature) as e:
@ -316,7 +315,8 @@ def verify_renewable_cert_sig(renewable_cert: interfaces.RenewableCert) -> None:
def verify_signed_payload(public_key: Union[DSAPublicKey, 'Ed25519PublicKey', 'Ed448PublicKey',
EllipticCurvePublicKey, RSAPublicKey],
EllipticCurvePublicKey, RSAPublicKey,
'X25519PublicKey', 'X448PublicKey'],
signature: bytes, payload: bytes,
signature_hash_algorithm: hashes.HashAlgorithm) -> None:
"""Check the signature of a payload.

View file

@ -285,6 +285,7 @@ def _check_ocsp_response_signature(response_ocsp: 'ocsp.OCSPResponse',
# Following line may raise UnsupportedAlgorithm
chosen_cert_hash = responder_cert.signature_hash_algorithm
assert chosen_cert_hash # always present for RSA and ECDSA certificates.
# For a delegate OCSP responder, we need first check that its certificate is effectively
# signed by the certificate issuer.
crypto_util.verify_signed_payload(issuer_cert.public_key(), responder_cert.signature,

View file

@ -20,6 +20,7 @@ from unittest import mock
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
import josepy as jose
from OpenSSL import crypto
import pkg_resources
@ -128,8 +129,9 @@ def load_rsa_private_key(*names: str) -> jose.ComparableRSAKey:
loader_fn = serialization.load_pem_private_key
else:
loader_fn = serialization.load_der_private_key
return jose.ComparableRSAKey(loader_fn(
load_vector(*names), password=None, backend=default_backend()))
return jose.ComparableRSAKey(
cast(RSAPrivateKey,
loader_fn(load_vector(*names), password=None, backend=default_backend())))
def load_pyopenssl_private_key(*names: str) -> crypto.PKey:

View file

@ -5,65 +5,64 @@
# requirements.txt so that is scanned by GitHub. See
# https://docs.github.com/en/github/visualizing-repository-data-with-graphs/about-the-dependency-graph#supported-package-ecosystems
# for more info.
alabaster==0.7.12 ; python_version >= "3.7" and python_version < "4.0"
alabaster==0.7.13 ; python_version >= "3.7" and python_version < "4.0"
apacheconfig==0.3.2 ; python_version >= "3.7" and python_version < "4.0"
appnope==0.1.3 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "darwin"
astroid==2.12.13 ; python_full_version >= "3.7.2" and python_version < "4.0"
astroid==2.13.5 ; python_full_version >= "3.7.2" and python_version < "4.0"
attrs==22.2.0 ; python_version >= "3.7" and python_version < "4.0"
azure-devops==6.0.0b4 ; python_version >= "3.7" and python_version < "4.0"
babel==2.11.0 ; python_version >= "3.7" and python_version < "4.0"
backcall==0.2.0 ; python_version >= "3.7" and python_version < "4.0"
backports-cached-property==1.0.2 ; python_version >= "3.7" and python_version < "3.8"
bcrypt==4.0.1 ; python_version >= "3.7" and python_version < "4.0"
beautifulsoup4==4.11.1 ; python_version >= "3.7" and python_version < "4.0"
bleach==5.0.1 ; python_version >= "3.7" and python_version < "4.0"
boto3==1.26.42 ; python_version >= "3.7" and python_version < "4.0"
botocore==1.29.42 ; python_version >= "3.7" and python_version < "4.0"
beautifulsoup4==4.11.2 ; python_version >= "3.7" and python_version < "4.0"
bleach==6.0.0 ; python_version >= "3.7" and python_version < "4.0"
boto3==1.26.65 ; python_version >= "3.7" and python_version < "4.0"
botocore==1.29.65 ; python_version >= "3.7" and python_version < "4.0"
cachecontrol==0.12.11 ; python_version >= "3.7" and python_version < "4.0"
cachetools==5.2.0 ; python_version >= "3.7" and python_version < "4.0"
cachetools==5.3.0 ; python_version >= "3.7" and python_version < "4.0"
cachy==0.3.0 ; python_version >= "3.7" and python_version < "4.0"
certifi==2022.12.7 ; python_version >= "3.7" and python_version < "4"
cffi==1.15.1 ; python_version >= "3.7" and python_version < "4.0"
charset-normalizer==2.1.1 ; python_version >= "3.7" and python_version < "4"
charset-normalizer==3.0.1 ; python_version >= "3.7" and python_version < "4"
cleo==1.0.0a5 ; python_version >= "3.7" and python_version < "4.0"
cloudflare==2.11.1 ; python_version >= "3.7" and python_version < "4.0"
colorama==0.4.6 ; python_version < "4.0" and sys_platform == "win32" and python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0" and platform_system == "Windows"
commonmark==0.9.1 ; python_version >= "3.7" and python_version < "4.0"
configargparse==1.5.3 ; python_version >= "3.7" and python_version < "4.0"
configobj==5.0.6 ; python_version >= "3.7" and python_version < "4.0"
coverage==7.0.3 ; python_version >= "3.7" and python_version < "4.0"
configobj==5.0.8 ; python_version >= "3.7" and python_version < "4.0"
coverage==7.1.0 ; python_version >= "3.7" and python_version < "4.0"
crashtest==0.3.1 ; python_version >= "3.7" and python_version < "4.0"
cryptography==39.0.0 ; python_version >= "3.7" and python_version < "4.0"
cython==0.29.32 ; python_version >= "3.7" and python_version < "4.0"
cryptography==39.0.1 ; python_version >= "3.7" and python_version < "4.0"
cython==0.29.33 ; python_version >= "3.7" and python_version < "4.0"
decorator==5.1.1 ; python_version >= "3.7" and python_version < "4.0"
dill==0.3.6 ; python_full_version >= "3.7.2" and python_version < "4.0"
distlib==0.3.6 ; python_version >= "3.7" and python_version < "4.0"
distro==1.8.0 ; python_version >= "3.7" and python_version < "4.0"
dns-lexicon==3.11.7 ; python_version >= "3.7" and python_version < "4.0"
dnspython==2.2.1 ; python_version >= "3.7" and python_version < "4.0"
dnspython==2.3.0 ; python_version >= "3.7" and python_version < "4.0"
docutils==0.17.1 ; python_version >= "3.7" and python_version < "4.0"
dulwich==0.20.50 ; python_version >= "3.7" and python_version < "4.0"
exceptiongroup==1.1.0 ; python_version >= "3.7" and python_version < "3.11"
execnet==1.9.0 ; python_version >= "3.7" and python_version < "4.0"
fabric==2.7.1 ; python_version >= "3.7" and python_version < "4.0"
fabric==3.0.0 ; python_version >= "3.7" and python_version < "4.0"
filelock==3.9.0 ; python_version >= "3.7" and python_version < "4.0"
google-api-core==2.11.0 ; python_version >= "3.7" and python_version < "4.0"
google-api-python-client==2.70.0 ; python_version >= "3.7" and python_version < "4.0"
google-api-python-client==2.77.0 ; python_version >= "3.7" and python_version < "4.0"
google-auth-httplib2==0.1.0 ; python_version >= "3.7" and python_version < "4.0"
google-auth==2.15.0 ; python_version >= "3.7" and python_version < "4.0"
googleapis-common-protos==1.57.0 ; python_version >= "3.7" and python_version < "4.0"
google-auth==2.16.0 ; python_version >= "3.7" and python_version < "4.0"
googleapis-common-protos==1.58.0 ; python_version >= "3.7" and python_version < "4.0"
html5lib==1.1 ; python_version >= "3.7" and python_version < "4.0"
httplib2==0.21.0 ; python_version >= "3.7" and python_version < "4.0"
idna==3.4 ; python_version >= "3.7" and python_version < "4"
imagesize==1.4.1 ; python_version >= "3.7" and python_version < "4.0"
importlib-metadata==4.13.0 ; python_version >= "3.7" and python_version < "4.0"
importlib-resources==5.10.2 ; python_version >= "3.7" and python_version < "3.9"
iniconfig==1.1.1 ; python_version >= "3.7" and python_version < "4.0"
invoke==1.7.3 ; python_version >= "3.7" and python_version < "4.0"
iniconfig==2.0.0 ; python_version >= "3.7" and python_version < "4.0"
invoke==2.0.0 ; python_version >= "3.7" and python_version < "4.0"
ipdb==0.13.11 ; python_version >= "3.7" and python_version < "4.0"
ipython==7.34.0 ; python_version >= "3.7" and python_version < "4.0"
isodate==0.6.1 ; python_version >= "3.7" and python_version < "4.0"
isort==5.11.4 ; python_full_version >= "3.7.2" and python_version < "4.0"
isort==5.11.5 ; python_full_version >= "3.7.2" and python_version < "4.0"
jaraco-classes==3.2.3 ; python_version >= "3.7" and python_version < "4.0"
jedi==0.18.2 ; python_version >= "3.7" and python_version < "4.0"
jeepney==0.8.0 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
@ -74,27 +73,28 @@ jsonlines==3.1.0 ; python_version >= "3.7" and python_version < "4.0"
jsonpickle==3.0.1 ; python_version >= "3.7" and python_version < "4.0"
jsonschema==4.17.3 ; python_version >= "3.7" and python_version < "4.0"
keyring==23.13.1 ; python_version >= "3.7" and python_version < "4.0"
lazy-object-proxy==1.8.0 ; python_full_version >= "3.7.2" and python_version < "4.0"
lazy-object-proxy==1.9.0 ; python_full_version >= "3.7.2" and python_version < "4.0"
lockfile==0.12.2 ; python_version >= "3.7" and python_version < "4.0"
markupsafe==2.1.1 ; python_version >= "3.7" and python_version < "4.0"
markdown-it-py==2.1.0 ; python_version >= "3.7" and python_version < "4.0"
markupsafe==2.1.2 ; python_version >= "3.7" and python_version < "4.0"
matplotlib-inline==0.1.6 ; python_version >= "3.7" and python_version < "4.0"
mccabe==0.7.0 ; python_full_version >= "3.7.2" and python_version < "4.0"
mdurl==0.1.2 ; python_version >= "3.7" and python_version < "4.0"
more-itertools==9.0.0 ; python_version >= "3.7" and python_version < "4.0"
msgpack==1.0.4 ; python_version >= "3.7" and python_version < "4.0"
msrest==0.6.21 ; python_version >= "3.7" and python_version < "4.0"
mypy-extensions==0.4.3 ; python_version >= "3.7" and python_version < "4.0"
mypy==0.991 ; python_version >= "3.7" and python_version < "4.0"
mypy-extensions==1.0.0 ; python_version >= "3.7" and python_version < "4.0"
mypy==1.0.0 ; python_version >= "3.7" and python_version < "4.0"
oauth2client==4.1.3 ; python_version >= "3.7" and python_version < "4.0"
oauthlib==3.2.2 ; python_version >= "3.7" and python_version < "4.0"
packaging==22.0 ; python_version >= "3.7" and python_version < "4.0"
paramiko==2.12.0 ; python_version >= "3.7" and python_version < "4.0"
packaging==23.0 ; python_version >= "3.7" and python_version < "4.0"
paramiko==3.0.0 ; python_version >= "3.7" and python_version < "4.0"
parsedatetime==2.6 ; python_version >= "3.7" and python_version < "4.0"
parso==0.8.3 ; python_version >= "3.7" and python_version < "4.0"
pathlib2==2.3.7.post1 ; python_version >= "3.7" and python_version < "4.0"
pexpect==4.8.0 ; python_version >= "3.7" and python_version < "4.0"
pickleshare==0.7.5 ; python_version >= "3.7" and python_version < "4.0"
pip==22.3.1 ; python_version >= "3.7" and python_version < "4.0"
pkginfo==1.9.3 ; python_version >= "3.7" and python_version < "4.0"
pip==23.0 ; python_version >= "3.7" and python_version < "4.0"
pkginfo==1.9.6 ; python_version >= "3.7" and python_version < "4.0"
pkgutil-resolve-name==1.3.10 ; python_version >= "3.7" and python_version < "3.9"
platformdirs==2.6.2 ; python_version < "4.0" and python_version >= "3.7"
pluggy==1.0.0 ; python_version >= "3.7" and python_version < "4.0"
@ -119,12 +119,12 @@ pyparsing==3.0.9 ; python_version >= "3.7" and python_version < "4.0"
pyrfc3339==1.1 ; python_version >= "3.7" and python_version < "4.0"
pyrsistent==0.19.3 ; python_version >= "3.7" and python_version < "4.0"
pytest-cov==4.0.0 ; python_version >= "3.7" and python_version < "4.0"
pytest-xdist==3.1.0 ; python_version >= "3.7" and python_version < "4.0"
pytest==7.2.0 ; python_version >= "3.7" and python_version < "4.0"
pytest-xdist==3.2.0 ; python_version >= "3.7" and python_version < "4.0"
pytest==7.2.1 ; python_version >= "3.7" and python_version < "4.0"
python-augeas==1.1.0 ; python_version >= "3.7" and python_version < "4.0"
python-dateutil==2.8.2 ; python_version >= "3.7" and python_version < "4.0"
python-digitalocean==1.17.0 ; python_version >= "3.7" and python_version < "4.0"
pytz==2022.7 ; python_version >= "3.7" and python_version < "4.0"
pytz==2022.7.1 ; python_version >= "3.7" and python_version < "4.0"
pywin32-ctypes==0.2.0 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32"
pywin32==305 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32"
pyyaml==6.0 ; python_version >= "3.7" and python_version < "4.0"
@ -133,15 +133,15 @@ requests-download==0.1.2 ; python_version >= "3.7" and python_version < "4.0"
requests-file==1.5.1 ; python_version >= "3.7" and python_version < "4.0"
requests-oauthlib==1.3.1 ; python_version >= "3.7" and python_version < "4.0"
requests-toolbelt==0.9.1 ; python_version >= "3.7" and python_version < "4.0"
requests==2.28.1 ; python_version >= "3.7" and python_version < "4"
requests==2.28.2 ; python_version >= "3.7" and python_version < "4"
rfc3986==2.0.0 ; python_version >= "3.7" and python_version < "4.0"
rich==13.0.0 ; python_version >= "3.7" and python_version < "4.0"
rich==13.3.1 ; python_version >= "3.7" and python_version < "4.0"
rsa==4.9 ; python_version >= "3.7" and python_version < "4"
s3transfer==0.6.0 ; python_version >= "3.7" and python_version < "4.0"
secretstorage==3.3.3 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
semantic-version==2.10.0 ; python_version >= "3.7" and python_version < "4.0"
setuptools-rust==1.5.2 ; python_version >= "3.7" and python_version < "4.0"
setuptools==65.6.3 ; python_version >= "3.7" and python_version < "4.0"
setuptools==67.2.0 ; python_version >= "3.7" and python_version < "4.0"
shellingham==1.5.0.post1 ; python_version >= "3.7" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.7" and python_version < "4.0"
snowballstemmer==2.2.0 ; python_version >= "3.7" and python_version < "4.0"
@ -158,26 +158,26 @@ tldextract==3.4.0 ; python_version >= "3.7" and python_version < "4.0"
tomli==2.0.1 ; python_version >= "3.7" and python_full_version <= "3.11.0a6"
tomlkit==0.11.6 ; python_version < "4.0" and python_version >= "3.7"
tox==3.28.0 ; python_version >= "3.7" and python_version < "4.0"
traitlets==5.8.0 ; python_version >= "3.7" and python_version < "4.0"
traitlets==5.9.0 ; python_version >= "3.7" and python_version < "4.0"
twine==4.0.2 ; python_version >= "3.7" and python_version < "4.0"
typed-ast==1.5.4 ; python_version < "3.8" and python_version >= "3.7"
types-cryptography==3.3.23.2 ; python_version >= "3.7" and python_version < "4.0"
types-pyopenssl==23.0.0.0 ; python_version >= "3.7" and python_version < "4.0"
types-docutils==0.19.1.3 ; python_version >= "3.7" and python_version < "4.0"
types-pyopenssl==23.0.0.2 ; python_version >= "3.7" and python_version < "4.0"
types-pyrfc3339==1.1.1.1 ; python_version >= "3.7" and python_version < "4.0"
types-python-dateutil==2.8.19.5 ; python_version >= "3.7" and python_version < "4.0"
types-pytz==2022.7.0.0 ; python_version >= "3.7" and python_version < "4.0"
types-requests==2.28.11.7 ; python_version >= "3.7" and python_version < "4.0"
types-setuptools==65.6.0.2 ; python_version >= "3.7" and python_version < "4.0"
types-python-dateutil==2.8.19.6 ; python_version >= "3.7" and python_version < "4.0"
types-pytz==2022.7.1.0 ; python_version >= "3.7" and python_version < "4.0"
types-requests==2.28.11.12 ; python_version >= "3.7" and python_version < "4.0"
types-setuptools==67.1.0.2 ; python_version >= "3.7" and python_version < "4.0"
types-six==1.16.21.4 ; python_version >= "3.7" and python_version < "4.0"
types-urllib3==1.26.25.4 ; python_version >= "3.7" and python_version < "4.0"
types-urllib3==1.26.25.5 ; python_version >= "3.7" and python_version < "4.0"
typing-extensions==4.4.0 ; python_version >= "3.7" and python_version < "4.0"
uritemplate==4.1.1 ; python_version >= "3.7" and python_version < "4.0"
urllib3==1.26.13 ; python_version >= "3.7" and python_version < "4.0"
virtualenv==20.17.1 ; python_version >= "3.7" and python_version < "4.0"
wcwidth==0.2.5 ; python_version >= "3.7" and python_version < "4.0"
urllib3==1.26.14 ; python_version >= "3.7" and python_version < "4.0"
virtualenv==20.18.0 ; python_version >= "3.7" and python_version < "4.0"
wcwidth==0.2.6 ; python_version >= "3.7" and python_version < "4.0"
webencodings==0.5.1 ; python_version >= "3.7" and python_version < "4.0"
wheel==0.38.4 ; python_version >= "3.7" and python_version < "4.0"
wrapt==1.14.1 ; python_full_version >= "3.7.2" and python_version < "4.0"
xattr==0.9.9 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "darwin"
yarg==0.1.9 ; python_version >= "3.7" and python_version < "4.0"
zipp==3.11.0 ; python_version >= "3.7" and python_version < "4.0"
zipp==3.12.1 ; python_version >= "3.7" and python_version < "4.0"