diff --git a/0001-import-MutableMapping-from-collections.abc.patch b/0001-import-MutableMapping-from-collections.abc.patch deleted file mode 100644 index 942b3c0..0000000 --- a/0001-import-MutableMapping-from-collections.abc.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e88a14f86390b22ee55a810d0cd1b68c32c54423 Mon Sep 17 00:00:00 2001 -From: Tomas Hrnciar -Date: Wed, 16 Jun 2021 13:29:20 +0200 -Subject: [PATCH] import MutableMapping from collections.abc - ---- - dns/namedict.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dnspython-1.16.0/dns/namedict.py b/dnspython-1.16.0/dns/namedict.py -index 37a1310..ae8d6a4 100644 ---- a/dns/namedict.py -+++ b/dns/namedict.py -@@ -27,12 +27,12 @@ - - """DNS name dictionary""" - --import collections -+from collections.abc import MutableMapping - import dns.name - from ._compat import xrange - - --class NameDict(collections.MutableMapping): -+class NameDict(MutableMapping): - """A dictionary whose keys are dns.name.Name objects. - - In addition to being like a regular Python dictionary, this --- -2.31.1 - diff --git a/715.patch b/715.patch deleted file mode 100644 index 874d896..0000000 --- a/715.patch +++ /dev/null @@ -1,242 +0,0 @@ -From beb705719827843940ecebe48ef8b8ba65d2b91c Mon Sep 17 00:00:00 2001 -From: Tim Burke -Date: Wed, 9 Jun 2021 14:40:13 -0700 -Subject: [PATCH 1/6] Only wrap socket.timeout on Python < 3.10 - -On py310, socket.timeout is TimeoutError, which our is_timeout() helper -func already knows is a timeout. - -Note that this doesn't get us to py310 support (not by a long shot), but -it's a step along the way. - -Closes #687 ---- - eventlet/greenio/base.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/eventlet/greenio/base.py b/eventlet/greenio/base.py -index 2eed86966..51a7ae13e 100644 ---- a/eventlet/greenio/base.py -+++ b/eventlet/greenio/base.py -@@ -29,7 +29,10 @@ - _original_socket = eventlet.patcher.original('socket').socket - - --socket_timeout = eventlet.timeout.wrap_is_timeout(socket.timeout) -+if sys.version_info >= (3, 10): -+ socket_timeout = socket.timeout # Really, TimeoutError -+else: -+ socket_timeout = eventlet.timeout.wrap_is_timeout(socket.timeout) - - - def socket_connect(descriptor, address): - -From c22a27ace90a55d14e8c60ff37f9832e76266441 Mon Sep 17 00:00:00 2001 -From: Tim Burke -Date: Fri, 11 Jun 2021 12:56:07 -0700 -Subject: [PATCH 2/6] Get a working greenio._open on py310 - -_pyio.open is now a staticmethod, which means we can't get at the -function code to wrap it up with a new environment. - -Instead, create a new wrapper function which swaps out FileIO for -GreenFileIO in the function's __globals__ before calling and replaces -it in a finally. ---- - eventlet/greenio/py3.py | 30 +++++++++++++++++++++++------- - 1 file changed, 23 insertions(+), 7 deletions(-) - -diff --git a/eventlet/greenio/py3.py b/eventlet/greenio/py3.py -index 7a75b52c0..c7f0aef50 100644 ---- a/eventlet/greenio/py3.py -+++ b/eventlet/greenio/py3.py -@@ -2,6 +2,7 @@ - import errno - import os as _original_os - import socket as _original_socket -+import sys - from io import ( - BufferedRandom as _OriginalBufferedRandom, - BufferedReader as _OriginalBufferedReader, -@@ -19,6 +20,7 @@ - SOCKET_BLOCKING, - ) - from eventlet.hubs import notify_close, notify_opened, IOClosed, trampoline -+from eventlet.semaphore import Semaphore - from eventlet.support import get_errno - import six - -@@ -182,21 +184,35 @@ def __exit__(self, *args): - self.close() - - --_open_environment = dict(globals()) --_open_environment.update(dict( -+_open_patching = dict( - BufferedRandom=_OriginalBufferedRandom, - BufferedWriter=_OriginalBufferedWriter, - BufferedReader=_OriginalBufferedReader, - TextIOWrapper=_OriginalTextIOWrapper, - FileIO=GreenFileIO, - os=_original_os, --)) -- --_open = FunctionType( -- six.get_function_code(_original_pyio.open), -- _open_environment, - ) - -+if sys.version_info < (3, 10): -+ _open_environment = dict(globals()) -+ _open_environment.update(_open_patching) -+ _open = FunctionType( -+ six.get_function_code(_original_pyio.open), -+ _open_environment, -+ ) -+else: -+ _open_lock = Semaphore() -+ _open_originals = {k: _original_pyio.open.__func__.__globals__[k] -+ for k in _open_patching} -+ -+ def _open(*a, **kw): -+ with _open_lock: -+ try: -+ _original_pyio.open.__func__.__globals__.update(_open_patching) -+ return _original_pyio.open(*a, **kw) -+ finally: -+ _original_pyio.open.__func__.__globals__.update(_open_originals) -+ - - def GreenPipe(name, mode="r", buffering=-1, encoding=None, errors=None, - newline=None, closefd=True, opener=None): - -From ab4f8aaa704eb56b1e15730268fffbc8724c53ea Mon Sep 17 00:00:00 2001 -From: Tim Burke -Date: Fri, 11 Jun 2021 13:02:52 -0700 -Subject: [PATCH 3/6] Test using eventlet.is_timeout - -...rather than requiring an is_timeout attribute on errors. - -TimeoutErrors (which are covered by is_timeout) can't necessarily have -attributes added to them. ---- - tests/__init__.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/__init__.py b/tests/__init__.py -index c0b64fd9e..188366774 100644 ---- a/tests/__init__.py -+++ b/tests/__init__.py -@@ -383,7 +383,7 @@ def run_isolated(path, prefix='tests/isolated/', **kwargs): - - def check_is_timeout(obj): - value_text = getattr(obj, 'is_timeout', '(missing)') -- assert obj.is_timeout, 'type={0} str={1} .is_timeout={2}'.format(type(obj), str(obj), value_text) -+ assert eventlet.is_timeout(obj), 'type={0} str={1} .is_timeout={2}'.format(type(obj), str(obj), value_text) - - - @contextlib.contextmanager - -From ceef941b6b730add07eff4a3d4da5d203e255a71 Mon Sep 17 00:00:00 2001 -From: Tim Burke -Date: Fri, 11 Jun 2021 13:07:09 -0700 -Subject: [PATCH 4/6] Fix backdoor tests on py310 - -Python 3.10 started including build info on the version line, so the -expectation in tests had to change. Also, start printing the banner as -we read it to aid in future debugging. ---- - tests/backdoor_test.py | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/tests/backdoor_test.py b/tests/backdoor_test.py -index 03a569259..67a817947 100644 ---- a/tests/backdoor_test.py -+++ b/tests/backdoor_test.py -@@ -1,5 +1,6 @@ - import os - import os.path -+import sys - - import eventlet - -@@ -21,10 +22,18 @@ def test_server(self): - - def _run_test_on_client_and_server(self, client, server_thread): - f = client.makefile('rw') -- assert 'Python' in f.readline() -- f.readline() # build info -- f.readline() # help info -- assert 'InteractiveConsole' in f.readline() -+ line = f.readline() -+ print(line.strip('\r\n')) -+ assert 'Python' in line -+ if sys.version_info < (3, 10): -+ # Starting in py310, build info is included in version line -+ line = f.readline() # build info -+ print(line.strip('\r\n')) -+ line = f.readline() # help info -+ print(line.strip('\r\n')) -+ line = f.readline() -+ print(line.strip('\r\n')) -+ assert 'InteractiveConsole' in line - self.assertEqual('>>> ', f.read(4)) - f.write('print("hi")\n') - f.flush() - -From aa6720a44cda816d1ac0a183ff94ebd51b6b1e53 Mon Sep 17 00:00:00 2001 -From: Tim Burke -Date: Fri, 11 Jun 2021 13:12:36 -0700 -Subject: [PATCH 5/6] Tolerate __builtins__ being a dict (rather than module) - in is_timeout - -I'm still not sure how this happens, but somehow it does in -socket_test.test_error_is_timeout. As a result, is_timeout wouldn't get -a reference to TimeoutError, so the socket error would not be correctly -identified as a timeout. ---- - eventlet/timeout.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/eventlet/timeout.py b/eventlet/timeout.py -index 6e1e08f63..969fdbcbd 100644 ---- a/eventlet/timeout.py -+++ b/eventlet/timeout.py -@@ -175,5 +175,8 @@ def fun(*args, **kwargs): - - - def is_timeout(obj): -- py3err = getattr(__builtins__, 'TimeoutError', Timeout) -+ if isinstance(__builtins__, dict): # seen when running tests on py310, but HOW?? -+ py3err = __builtins__.get('TimeoutError', Timeout) -+ else: -+ py3err = getattr(__builtins__, 'TimeoutError', Timeout) - return bool(getattr(obj, 'is_timeout', False)) or isinstance(obj, py3err) - -From 900c8e195154efdae526ee7901469152141ab9d2 Mon Sep 17 00:00:00 2001 -From: Tim Burke -Date: Fri, 11 Jun 2021 13:33:00 -0700 -Subject: [PATCH 6/6] wsgi_test: Cap TLS version at 1.2 - -On py310, tests may attempt to use TLS 1.3 which apparently doesn't like -the abrupt disconnect. Instead, it would complain: - - ssl.SSLEOFError: EOF occurred in violation of protocol ---- - tests/wsgi_test.py | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/wsgi_test.py b/tests/wsgi_test.py -index 1dd754bba..4173bcefa 100644 ---- a/tests/wsgi_test.py -+++ b/tests/wsgi_test.py -@@ -579,7 +579,8 @@ def wsgi_app(environ, start_response): - sock = eventlet.wrap_ssl( - eventlet.listen(('localhost', 0)), - certfile=certificate_file, keyfile=private_key_file, -- server_side=True) -+ server_side=True, -+ ssl_version=ssl.PROTOCOL_TLSv1_2) - server_coro = eventlet.spawn(server, sock, wsgi_app, self.logfile) - - client = eventlet.connect(('localhost', sock.getsockname()[1])) diff --git a/python-eventlet.spec b/python-eventlet.spec index 3aa77c3..cc1cb53 100644 --- a/python-eventlet.spec +++ b/python-eventlet.spec @@ -1,25 +1,14 @@ %global modname eventlet -%global bundle_dns 0 %{?python_enable_dependency_generator} Name: python-%{modname} Version: 0.33.1 Release: 3%{?dist} Summary: Highly concurrent networking library -%if %bundle_dns -License: MIT and ISC -%else License: MIT -%endif URL: http://eventlet.net Source0: https://github.com/eventlet/%{modname}/archive/v%{version}.zip -Source1: %{pypi_source dnspython 1.16.0 zip} -Patch0: switch_to_python_cryptography.patch - -# Since Python 3.10 MutableMapping is available in collections.abc instead of collections. -# This is already fixed in dnspython 2.0.0+, but eventlet still uses old 1.16.0. -Patch1: 0001-import-MutableMapping-from-collections.abc.patch BuildArch: noarch @@ -40,14 +29,8 @@ BuildRequires: python3dist(six) >= 1.10 BuildRequires: python3-nose BuildRequires: python3-pyOpenSSL -%if %bundle_dns -Provides: bundled(python3dist(dnspython)) = 1.16.0 -BuildRequires: python3-cryptography -Recommends: python3-cryptography -%else BuildRequires: python3dist(dnspython) >= 1.15 BuildRequires: python3dist(dnspython) < 3 -%endif %{?python_provide:%python_provide python3-%{modname}} @@ -67,28 +50,10 @@ BuildRequires: python3-zmq %{summary}. %prep -%if %bundle_dns -%setup -n %{modname}-%{version} -q -a1 -%else %setup -n %{modname}-%{version} -q -%endif # Remove dependency on enum-compat from setup.py # enum-compat is not needed for Python 3 sed -i "/'enum-compat',/d" setup.py -%if %bundle_dns -# We bundle last version of dns1 as eventlet does not support yet dns2 -pushd dnspython-1.16.0 -%patch -P 0 -p1 -%patch -P 1 -p1 -grep -lRZ "dns\." dns | xargs -0 -l sed -i -e 's/\([^[a-zA-Z]\)dns\./\1eventlet\.dns\./g' -grep -lRZ "^import dns$" dns | xargs -0 -l sed -i -e 's/^import\ dns$/import\ eventlet\.dns/' -popd -mv dnspython-1.16.0/dns eventlet -sed -i '/dnspython >= 1.15.0, < 2.0.0/d' setup.py -sed -i "s/import_patched('dns/import_patched('eventlet\.dns/g" eventlet/support/greendns.py -cp -a dnspython-1.16.0/LICENSE LICENSE.dns -rm -vrf dnspython-1.16.0 -%endif rm -vrf *.egg-info %build @@ -112,9 +77,6 @@ nosetests-%{python3_version} -v -e greendns_test -e socket_test -e test_patcher_ %files -n python3-%{modname} %doc README.rst AUTHORS LICENSE NEWS %license LICENSE -%if %bundle_dns -%license LICENSE.dns -%endif %{python3_sitelib}/%{modname}/ %{python3_sitelib}/%{modname}-*.egg-info/ diff --git a/switch_to_python_cryptography.patch b/switch_to_python_cryptography.patch deleted file mode 100644 index a5ced51..0000000 --- a/switch_to_python_cryptography.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 087df702931f32eeb3a29957a8fe3fa31749d642 Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Tue, 28 Apr 2020 10:08:02 +0200 -Subject: [PATCH] Switch to python cryptography - -Original patch: https://github.com/simo5/dnspython/commit/bfe84d523bd4fde7b2655857d78bba85ed05f43c -The same change in master: https://github.com/rthalley/dnspython/pull/449 ---- - dns/dnssec.py | 168 ++++++++++++++++++++----------------------- - setup.py | 2 +- - tests/test_dnssec.py | 12 +--- - 3 files changed, 79 insertions(+), 103 deletions(-) - -diff --git a/dns/dnssec.py b/dns/dnssec.py -index 35da6b5..73e92da 100644 ---- a/dns/dnssec.py -+++ b/dns/dnssec.py -@@ -17,6 +17,7 @@ - - """Common DNSSEC-related functions and constants.""" - -+import hashlib # used in make_ds() to avoid pycrypto dependency - from io import BytesIO - import struct - import time -@@ -165,10 +166,10 @@ def make_ds(name, key, algorithm, origin=None): - - if algorithm.upper() == 'SHA1': - dsalg = 1 -- hash = SHA1.new() -+ hash = hashlib.sha1() - elif algorithm.upper() == 'SHA256': - dsalg = 2 -- hash = SHA256.new() -+ hash = hashlib.sha256() - else: - raise UnsupportedAlgorithm('unsupported algorithm "%s"' % algorithm) - -@@ -214,7 +215,7 @@ def _is_dsa(algorithm): - - - def _is_ecdsa(algorithm): -- return _have_ecdsa and (algorithm in (ECDSAP256SHA256, ECDSAP384SHA384)) -+ return (algorithm in (ECDSAP256SHA256, ECDSAP384SHA384)) - - - def _is_md5(algorithm): -@@ -240,18 +241,26 @@ def _is_sha512(algorithm): - - def _make_hash(algorithm): - if _is_md5(algorithm): -- return MD5.new() -+ return hashes.MD5() - if _is_sha1(algorithm): -- return SHA1.new() -+ return hashes.SHA1() - if _is_sha256(algorithm): -- return SHA256.new() -+ return hashes.SHA256() - if _is_sha384(algorithm): -- return SHA384.new() -+ return hashes.SHA384() - if _is_sha512(algorithm): -- return SHA512.new() -+ return hashes.SHA512() -+ if algorithm == ED25519: -+ return hashes.SHA512() -+ if algorithm == ED448: -+ return hashes.SHAKE256(114) - raise ValidationFailure('unknown hash for algorithm %u' % algorithm) - - -+def _bytes_to_long(b): -+ return int.from_bytes(b, 'big') -+ -+ - def _make_algorithm_id(algorithm): - if _is_md5(algorithm): - oid = [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05] -@@ -316,8 +325,6 @@ def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): - if rrsig.inception > now: - raise ValidationFailure('not yet valid') - -- hash = _make_hash(rrsig.algorithm) -- - if _is_rsa(rrsig.algorithm): - keyptr = candidate_key.key - (bytes_,) = struct.unpack('!B', keyptr[0:1]) -@@ -328,9 +335,9 @@ def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): - rsa_e = keyptr[0:bytes_] - rsa_n = keyptr[bytes_:] - try: -- pubkey = CryptoRSA.construct( -- (number.bytes_to_long(rsa_n), -- number.bytes_to_long(rsa_e))) -+ public_key = rsa.RSAPublicNumbers( -+ _bytes_to_long(rsa_e), -+ _bytes_to_long(rsa_n)).public_key(default_backend()) - except ValueError: - raise ValidationFailure('invalid public key') - sig = rrsig.signature -@@ -346,42 +353,47 @@ def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): - dsa_g = keyptr[0:octets] - keyptr = keyptr[octets:] - dsa_y = keyptr[0:octets] -- pubkey = CryptoDSA.construct( -- (number.bytes_to_long(dsa_y), -- number.bytes_to_long(dsa_g), -- number.bytes_to_long(dsa_p), -- number.bytes_to_long(dsa_q))) -- sig = rrsig.signature[1:] -+ try: -+ public_key = dsa.DSAPublicNumbers( -+ _bytes_to_long(dsa_y), -+ dsa.DSAParameterNumbers( -+ _bytes_to_long(dsa_p), -+ _bytes_to_long(dsa_q), -+ _bytes_to_long(dsa_g))).public_key(default_backend()) -+ except ValueError: -+ raise ValidationFailure('invalid public key') -+ sig_r = rrsig.signature[1:21] -+ sig_s = rrsig.signature[21:] -+ sig = utils.encode_dss_signature(_bytes_to_long(sig_r), -+ _bytes_to_long(sig_s)) - elif _is_ecdsa(rrsig.algorithm): -- # use ecdsa for NIST-384p -- not currently supported by pycryptodome -- - keyptr = candidate_key.key -- - if rrsig.algorithm == ECDSAP256SHA256: -- curve = ecdsa.curves.NIST256p -- key_len = 32 -+ curve = ec.SECP256R1() -+ octets = 32 - elif rrsig.algorithm == ECDSAP384SHA384: -- curve = ecdsa.curves.NIST384p -- key_len = 48 -- -- x = number.bytes_to_long(keyptr[0:key_len]) -- y = number.bytes_to_long(keyptr[key_len:key_len * 2]) -- if not ecdsa.ecdsa.point_is_valid(curve.generator, x, y): -- raise ValidationFailure('invalid ECDSA key') -- point = ecdsa.ellipticcurve.Point(curve.curve, x, y, curve.order) -- verifying_key = ecdsa.keys.VerifyingKey.from_public_point(point, -- curve) -- pubkey = ECKeyWrapper(verifying_key, key_len) -- r = rrsig.signature[:key_len] -- s = rrsig.signature[key_len:] -- sig = ecdsa.ecdsa.Signature(number.bytes_to_long(r), -- number.bytes_to_long(s)) -+ curve = ec.SECP384R1() -+ octets = 48 -+ ecdsa_x = keyptr[0:octets] -+ ecdsa_y = keyptr[octets:octets * 2] -+ try: -+ public_key = ec.EllipticCurvePublicNumbers( -+ curve=curve, -+ x=_bytes_to_long(ecdsa_x), -+ y=_bytes_to_long(ecdsa_y)).public_key(default_backend()) -+ except ValueError: -+ raise ValidationFailure('invalid public key') -+ sig_r = rrsig.signature[0:octets] -+ sig_s = rrsig.signature[octets:] -+ sig = utils.encode_dss_signature(_bytes_to_long(sig_r), -+ _bytes_to_long(sig_s)) - - else: - raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm) - -- hash.update(_to_rdata(rrsig, origin)[:18]) -- hash.update(rrsig.signer.to_digestable(origin)) -+ data = b'' -+ data += _to_rdata(rrsig, origin)[:18] -+ data += rrsig.signer.to_digestable(origin) - - if rrsig.labels < len(rrname) - 1: - suffix = rrname.split(rrsig.labels + 1)[1] -@@ -391,25 +403,21 @@ def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): - rrsig.original_ttl) - rrlist = sorted(rdataset) - for rr in rrlist: -- hash.update(rrnamebuf) -- hash.update(rrfixed) -+ data += rrnamebuf -+ data += rrfixed - rrdata = rr.to_digestable(origin) - rrlen = struct.pack('!H', len(rrdata)) -- hash.update(rrlen) -- hash.update(rrdata) -+ data += rrlen -+ data += rrdata - -+ chosen_hash = _make_hash(rrsig.algorithm) - try: - if _is_rsa(rrsig.algorithm): -- verifier = pkcs1_15.new(pubkey) -- # will raise ValueError if verify fails: -- verifier.verify(hash, sig) -+ public_key.verify(sig, data, padding.PKCS1v15(), chosen_hash) - elif _is_dsa(rrsig.algorithm): -- verifier = DSS.new(pubkey, 'fips-186-3') -- verifier.verify(hash, sig) -+ public_key.verify(sig, data, chosen_hash) - elif _is_ecdsa(rrsig.algorithm): -- digest = hash.digest() -- if not pubkey.verify(digest, sig): -- raise ValueError -+ public_key.verify(sig, data, ec.ECDSA(chosen_hash)) - else: - # Raise here for code clarity; this won't actually ever happen - # since if the algorithm is really unknown we'd already have -@@ -417,7 +425,7 @@ def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): - raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm) - # If we got here, we successfully verified so we can return without error - return -- except ValueError: -+ except InvalidSignature: - # this happens on an individual validation failure - continue - # nothing verified -- raise failure: -@@ -472,48 +480,24 @@ def _validate(rrset, rrsigset, keys, origin=None, now=None): - raise ValidationFailure("no RRSIGs validated") - - --def _need_pycrypto(*args, **kwargs): -- raise NotImplementedError("DNSSEC validation requires pycryptodome/pycryptodomex") -+def _need_pyca(*args, **kwargs): -+ raise NotImplementedError("DNSSEC validation requires python cryptography") - - - try: -- try: -- # test we're using pycryptodome, not pycrypto (which misses SHA1 for example) -- from Crypto.Hash import MD5, SHA1, SHA256, SHA384, SHA512 -- from Crypto.PublicKey import RSA as CryptoRSA, DSA as CryptoDSA -- from Crypto.Signature import pkcs1_15, DSS -- from Crypto.Util import number -- except ImportError: -- from Cryptodome.Hash import MD5, SHA1, SHA256, SHA384, SHA512 -- from Cryptodome.PublicKey import RSA as CryptoRSA, DSA as CryptoDSA -- from Cryptodome.Signature import pkcs1_15, DSS -- from Cryptodome.Util import number -+ from cryptography.exceptions import InvalidSignature -+ from cryptography.hazmat.backends import default_backend -+ from cryptography.hazmat.primitives import hashes -+ from cryptography.hazmat.primitives.asymmetric import padding -+ from cryptography.hazmat.primitives.asymmetric import utils -+ from cryptography.hazmat.primitives.asymmetric import dsa -+ from cryptography.hazmat.primitives.asymmetric import ec -+ from cryptography.hazmat.primitives.asymmetric import rsa - except ImportError: -- validate = _need_pycrypto -- validate_rrsig = _need_pycrypto -- _have_pycrypto = False -- _have_ecdsa = False -+ validate = _need_pyca -+ validate_rrsig = _need_pyca -+ _have_pyca = False - else: - validate = _validate - validate_rrsig = _validate_rrsig -- _have_pycrypto = True -- -- try: -- import ecdsa -- import ecdsa.ecdsa -- import ecdsa.ellipticcurve -- import ecdsa.keys -- except ImportError: -- _have_ecdsa = False -- else: -- _have_ecdsa = True -- -- class ECKeyWrapper(object): -- -- def __init__(self, key, key_len): -- self.key = key -- self.key_len = key_len -- -- def verify(self, digest, sig): -- diglong = number.bytes_to_long(digest) -- return self.key.pubkey.verifies(diglong, sig) -+ _have_pyca = True -diff --git a/setup.py b/setup.py -index 743d43c..2ee38a7 100755 ---- a/setup.py -+++ b/setup.py -@@ -75,7 +75,7 @@ direct manipulation of DNS zones, messages, names, and records.""", - 'provides': ['dns'], - 'extras_require': { - 'IDNA': ['idna>=2.1'], -- 'DNSSEC': ['pycryptodome', 'ecdsa>=0.13'], -+ 'DNSSEC': ['cryptography>=2.3'], - }, - 'ext_modules': ext_modules if compile_cython else None, - 'zip_safe': False if compile_cython else None, -diff --git a/tests/test_dnssec.py b/tests/test_dnssec.py -index c87862a..20b52b2 100644 ---- a/tests/test_dnssec.py -+++ b/tests/test_dnssec.py -@@ -151,8 +151,8 @@ abs_ecdsa384_soa_rrsig = dns.rrset.from_text('example.', 86400, 'IN', 'RRSIG', - - - --@unittest.skipUnless(dns.dnssec._have_pycrypto, -- "Pycryptodome cannot be imported") -+@unittest.skipUnless(dns.dnssec._have_pyca, -+ "Python Cryptography cannot be imported") - class DNSSECValidatorTestCase(unittest.TestCase): - - def testAbsoluteRSAGood(self): # type: () -> None -@@ -199,28 +199,20 @@ class DNSSECValidatorTestCase(unittest.TestCase): - ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA256') - self.failUnless(ds == example_ds_sha256) - -- @unittest.skipUnless(dns.dnssec._have_ecdsa, -- "python ECDSA cannot be imported") - def testAbsoluteECDSA256Good(self): # type: () -> None - dns.dnssec.validate(abs_ecdsa256_soa, abs_ecdsa256_soa_rrsig, - abs_ecdsa256_keys, None, when3) - -- @unittest.skipUnless(dns.dnssec._have_ecdsa, -- "python ECDSA cannot be imported") - def testAbsoluteECDSA256Bad(self): # type: () -> None - def bad(): # type: () -> None - dns.dnssec.validate(abs_other_ecdsa256_soa, abs_ecdsa256_soa_rrsig, - abs_ecdsa256_keys, None, when3) - self.failUnlessRaises(dns.dnssec.ValidationFailure, bad) - -- @unittest.skipUnless(dns.dnssec._have_ecdsa, -- "python ECDSA cannot be imported") - def testAbsoluteECDSA384Good(self): # type: () -> None - dns.dnssec.validate(abs_ecdsa384_soa, abs_ecdsa384_soa_rrsig, - abs_ecdsa384_keys, None, when4) - -- @unittest.skipUnless(dns.dnssec._have_ecdsa, -- "python ECDSA cannot be imported") - def testAbsoluteECDSA384Bad(self): # type: () -> None - def bad(): # type: () -> None - dns.dnssec.validate(abs_other_ecdsa384_soa, abs_ecdsa384_soa_rrsig, --- -2.26.2 -