diff --git a/src/aws_encryption_sdk/internal/crypto/authentication.py b/src/aws_encryption_sdk/internal/crypto/authentication.py index 560fdb2a2..f90ac77e0 100644 --- a/src/aws_encryption_sdk/internal/crypto/authentication.py +++ b/src/aws_encryption_sdk/internal/crypto/authentication.py @@ -18,7 +18,6 @@ from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric.utils import Prehashed -from cryptography.utils import InterfaceNotImplemented, verify_interface from ...exceptions import NotSupportedError from .elliptic_curve import ( @@ -47,11 +46,9 @@ def __init__(self, algorithm, key): def _set_signature_type(self): """Ensures that the algorithm signature type is a known type and sets a reference value.""" - try: - verify_interface(ec.EllipticCurve, self.algorithm.signing_algorithm_info) - return ec.EllipticCurve - except InterfaceNotImplemented: + if not isinstance(self.algorithm.signing_algorithm_info, type(ec.EllipticCurve)): raise NotSupportedError("Unsupported signing algorithm info") + return ec.EllipticCurve def _build_hasher(self): """Builds the hasher instance which will calculate the digest of all passed data. diff --git a/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py b/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py index 0febe7cc8..d2edde317 100644 --- a/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py +++ b/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py @@ -18,14 +18,13 @@ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric.utils import Prehashed, decode_dss_signature, encode_dss_signature -from cryptography.utils import InterfaceNotImplemented, int_to_bytes, verify_interface +from cryptography.utils import int_to_bytes from ...exceptions import NotSupportedError from ..str_ops import to_bytes _LOGGER = logging.getLogger(__name__) - # Curve parameter values are included strictly as a temporary measure # until they can be rolled into the cryptography.io library. # Expanded values from http://www.secg.org/sec2-v2.pdf @@ -44,10 +43,10 @@ order=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973, ), "secp521r1": _ECCCurveParameters( - p=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa pylint: disable=line-too-long - a=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC, # noqa pylint: disable=line-too-long - b=0x0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00, # noqa pylint: disable=line-too-long - order=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409, # noqa pylint: disable=line-too-long + p=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa pylint: disable=line-too-long + a=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC, # noqa pylint: disable=line-too-long + b=0x0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00, # noqa pylint: disable=line-too-long + order=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409, # noqa pylint: disable=line-too-long ), } @@ -182,8 +181,6 @@ def generate_ecc_signing_key(algorithm): :returns: Generated signing key :raises NotSupportedError: if signing algorithm is not supported on this platform """ - try: - verify_interface(ec.EllipticCurve, algorithm.signing_algorithm_info) - return ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend()) - except InterfaceNotImplemented: + if not isinstance(algorithm.signing_algorithm_info, type(ec.EllipticCurve)): raise NotSupportedError("Unsupported signing algorithm info") + return ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend()) diff --git a/test/unit/test_crypto_authentication_signer.py b/test/unit/test_crypto_authentication_signer.py index 440fa4f9b..11271abfb 100644 --- a/test/unit/test_crypto_authentication_signer.py +++ b/test/unit/test_crypto_authentication_signer.py @@ -30,6 +30,12 @@ def patch_default_backend(mocker): yield aws_encryption_sdk.internal.crypto.authentication.default_backend +@pytest.fixture +def patch_ec(mocker): + mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "ec") + yield aws_encryption_sdk.internal.crypto.authentication.ec + + @pytest.fixture def patch_serialization(mocker): mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "serialization") @@ -71,8 +77,10 @@ def test_f_signer_key_bytes(): assert test.key_bytes() == VALUES["ecc_private_key_prime_private_bytes"] -def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher): - _algorithm = MagicMock() +def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec): + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + _algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) + signer = Signer.from_key_bytes(algorithm=_algorithm, key_bytes=sentinel.key_bytes) patch_serialization.load_der_private_key.assert_called_once_with( @@ -83,9 +91,11 @@ def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch assert signer.key is patch_serialization.load_der_private_key.return_value -def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher): +def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec): + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) private_key = MagicMock() - signer = Signer(MagicMock(), key=private_key) + signer = Signer(algorithm, key=private_key) test = signer.key_bytes() @@ -98,13 +108,21 @@ def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_buil def test_signer_encoded_public_key( - patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_encode_compressed_point, patch_base64 + patch_default_backend, + patch_serialization, + patch_build_hasher, + patch_ecc_encode_compressed_point, + patch_base64, + patch_ec ): patch_ecc_encode_compressed_point.return_value = sentinel.compressed_point patch_base64.b64encode.return_value = sentinel.encoded_point private_key = MagicMock() - signer = Signer(MagicMock(), key=private_key) + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) + + signer = Signer(algorithm, key=private_key) test_key = signer.encoded_public_key() patch_ecc_encode_compressed_point.assert_called_once_with(private_key) @@ -112,16 +130,19 @@ def test_signer_encoded_public_key( assert test_key == sentinel.encoded_point -def test_signer_update(patch_default_backend, patch_serialization, patch_build_hasher): - signer = Signer(MagicMock(), key=MagicMock()) +def test_signer_update(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec): + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) + signer = Signer(algorithm, key=MagicMock()) signer.update(sentinel.data) patch_build_hasher.return_value.update.assert_called_once_with(sentinel.data) def test_signer_finalize( - patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_static_length_signature + patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_static_length_signature, patch_ec ): - algorithm = MagicMock() + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) private_key = MagicMock() signer = Signer(algorithm, key=private_key) diff --git a/test/unit/test_crypto_authentication_verifier.py b/test/unit/test_crypto_authentication_verifier.py index b75d1c310..05af581eb 100644 --- a/test/unit/test_crypto_authentication_verifier.py +++ b/test/unit/test_crypto_authentication_verifier.py @@ -86,6 +86,7 @@ def test_f_verifier_key_bytes(): def test_verifier_from_encoded_point( patch_default_backend, patch_serialization, + patch_ec, patch_ecc_public_numbers_from_compressed_point, patch_base64, patch_build_hasher, @@ -94,21 +95,24 @@ def test_verifier_from_encoded_point( mock_point_instance.public_key.return_value = sentinel.public_key patch_ecc_public_numbers_from_compressed_point.return_value = mock_point_instance patch_base64.b64decode.return_value = sentinel.compressed_point - algorithm = MagicMock() + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) - verifier = Verifier.from_encoded_point(algorithm=algorithm, encoded_point=sentinel.encoded_point) + verifier = Verifier.from_encoded_point(algorithm=mock_algorithm, encoded_point=sentinel.encoded_point) patch_base64.b64decode.assert_called_once_with(sentinel.encoded_point) - algorithm.signing_algorithm_info.assert_called_once_with() + mock_algorithm.signing_algorithm_info.assert_called_once_with() patch_ecc_public_numbers_from_compressed_point.assert_called_once_with( - curve=algorithm.signing_algorithm_info.return_value, compressed_point=sentinel.compressed_point + curve=mock_algorithm.signing_algorithm_info.return_value, compressed_point=sentinel.compressed_point ) mock_point_instance.public_key.assert_called_once_with(patch_default_backend.return_value) assert isinstance(verifier, Verifier) -def test_verifier_update(patch_default_backend, patch_serialization, patch_build_hasher): - verifier = Verifier(algorithm=MagicMock(), key=MagicMock()) +def test_verifier_update(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec): + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) + mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) + verifier = Verifier(algorithm=mock_algorithm, key=MagicMock()) verifier.update(sentinel.data) verifier._hasher.update.assert_called_once_with(sentinel.data) diff --git a/test/unit/test_crypto_elliptic_curve.py b/test/unit/test_crypto_elliptic_curve.py index 445a28c79..02497b31c 100644 --- a/test/unit/test_crypto_elliptic_curve.py +++ b/test/unit/test_crypto_elliptic_curve.py @@ -15,7 +15,6 @@ import pytest from cryptography.hazmat.primitives.asymmetric import ec -from cryptography.utils import InterfaceNotImplemented from mock import MagicMock, sentinel from pytest_mock import mocker # noqa pylint: disable=unused-import @@ -374,22 +373,20 @@ def test_ecc_public_numbers_from_compressed_point(patch_ec, patch_ecc_decode_com assert test == sentinel.public_numbers_instance -def test_generate_ecc_signing_key_supported(patch_default_backend, patch_ec, patch_verify_interface): +def test_generate_ecc_signing_key_supported(patch_default_backend, patch_ec): patch_ec.generate_private_key.return_value = sentinel.raw_signing_key - mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info) + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve) mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) test_signing_key = generate_ecc_signing_key(algorithm=mock_algorithm) - patch_verify_interface.assert_called_once_with(patch_ec.EllipticCurve, mock_algorithm_info) patch_ec.generate_private_key.assert_called_once_with( curve=sentinel.algorithm_info, backend=patch_default_backend.return_value ) assert test_signing_key is sentinel.raw_signing_key -def test_generate_ecc_signing_key_unsupported(patch_default_backend, patch_ec, patch_verify_interface): - patch_verify_interface.side_effect = InterfaceNotImplemented +def test_generate_ecc_signing_key_unsupported(patch_default_backend, patch_ec): mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info) mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) diff --git a/test/unit/test_crypto_prehashing_authenticator.py b/test/unit/test_crypto_prehashing_authenticator.py index 158872f8c..104133da0 100644 --- a/test/unit/test_crypto_prehashing_authenticator.py +++ b/test/unit/test_crypto_prehashing_authenticator.py @@ -12,7 +12,6 @@ # language governing permissions and limitations under the License. """Unit test suite for ``aws_encryption_sdk.internal.crypto._PrehashingAuthenticater``.""" import pytest -from cryptography.utils import InterfaceNotImplemented from mock import MagicMock, sentinel from pytest_mock import mocker # noqa pylint: disable=unused-import @@ -35,12 +34,6 @@ def patch_build_hasher(mocker): yield _PrehashingAuthenticator._build_hasher -@pytest.fixture -def patch_cryptography_utils_verify_interface(mocker): - mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "verify_interface") - yield aws_encryption_sdk.internal.crypto.authentication.verify_interface - - @pytest.fixture def patch_cryptography_ec(mocker): mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "ec") @@ -71,21 +64,18 @@ def test_init(patch_set_signature_type, patch_build_hasher): def test_set_signature_type_elliptic_curve( - patch_build_hasher, patch_cryptography_utils_verify_interface, patch_cryptography_ec + patch_build_hasher, patch_cryptography_ec ): - mock_algorithm = MagicMock() + mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_cryptography_ec.EllipticCurve) + mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info) test = _PrehashingAuthenticator(algorithm=mock_algorithm, key=sentinel.key) - patch_cryptography_utils_verify_interface.assert_called_once_with( - patch_cryptography_ec.EllipticCurve, mock_algorithm.signing_algorithm_info - ) assert test._signature_type is patch_cryptography_ec.EllipticCurve def test_set_signature_type_unknown( - patch_build_hasher, patch_cryptography_utils_verify_interface, patch_cryptography_ec + patch_build_hasher, patch_cryptography_ec ): - patch_cryptography_utils_verify_interface.side_effect = InterfaceNotImplemented with pytest.raises(NotSupportedError) as excinfo: _PrehashingAuthenticator(algorithm=MagicMock(), key=sentinel.key) diff --git a/test_vector_handlers/src/pylintrc b/test_vector_handlers/src/pylintrc index c78fe416a..dc5d95fff 100644 --- a/test_vector_handlers/src/pylintrc +++ b/test_vector_handlers/src/pylintrc @@ -1,4 +1,4 @@ -[MESSAGES CONTROL] +[MESSAGE CONTROL] # Disabling messages that we either don't care about for tests or are necessary to break for tests. disable = bad-continuation, # we let black handle this diff --git a/test_vector_handlers/tox.ini b/test_vector_handlers/tox.ini index 7418b2e98..10be9652d 100644 --- a/test_vector_handlers/tox.ini +++ b/test_vector_handlers/tox.ini @@ -105,12 +105,7 @@ commands = # Linters [testenv:flake8] basepython = python3 -deps = - .. - flake8 - flake8-docstrings - # https://github.com/JBKahn/flake8-print/pull/30 - flake8-print>=3.1.0 +deps = -r../dev_requirements/linter-requirements.txt commands = flake8 \ src/awses_test_vectors/ \ @@ -120,25 +115,20 @@ commands = [testenv:flake8-tests] basepython = {[testenv:flake8]basepython} -deps = - .. - flake8 +deps = -r../dev_requirements/linter-requirements.txt commands = flake8 \ # Ignore F811 redefinition errors in tests (breaks with pytest-mock use) # E203 is not PEP8 compliant https://github.com/ambv/black#slices # W503 is not PEP8 compliant https://github.com/ambv/black#line-breaks--binary-operators - --ignore F811,E203,W503 \ - test/ \ - {posargs} + --ignore F811,E203,W503,D \ + test/ [testenv:pylint] basepython = python3 deps = -rtest/requirements.txt - .. - pyflakes - pylint + -r../dev_requirements/linter-requirements.txt commands = pylint \ --rcfile=src/pylintrc \ @@ -157,8 +147,7 @@ commands = [testenv:blacken-src] basepython = python3 -deps = - black +deps = -r../dev_requirements/linter-requirements.txt commands = black --line-length 120 \ src/awses_test_vectors/ \ @@ -184,14 +173,12 @@ commands = [testenv:isort-seed] basepython = python3 -deps = seed-isort-config +deps = -r../dev_requirements/linter-requirements.txt commands = seed-isort-config [testenv:isort] basepython = python3 -deps = - isort - .. +deps = -r../dev_requirements/linter-requirements.txt commands = isort -rc \ src \ test \ @@ -216,29 +203,23 @@ commands = [testenv:doc8] basepython = python3 -deps = - sphinx - doc8 +deps = -r../dev_requirements/linter-requirements.txt commands = doc8 doc/index.rst README.rst CHANGELOG.rst [testenv:readme] basepython = python3 -deps = - .. - readme_renderer +deps = -r../dev_requirements/linter-requirements.txt commands = python setup.py check -r -s [testenv:bandit] basepython = python3 -deps = - .. - bandit>=1.5.1 +deps = -r../dev_requirements/linter-requirements.txt commands = bandit -r src/awses_test_vectors/ # Prone to false positives: only run independently [testenv:vulture] basepython = python3 -deps = vulture +deps = -r../dev_requirements/linter-requirements.txt commands = vulture src/awses_test_vectors/ [testenv:linters] @@ -284,9 +265,7 @@ commands = [testenv:park] basepython = python3 skip_install = true -deps = - pypi-parker - setuptools +deps = -r../dev_requirements/release-requirements.txt commands = python setup.py park [testenv:build] @@ -294,8 +273,7 @@ basepython = python3 skip_install = true deps = {[testenv:docs]deps} - wheel - setuptools + -r../dev_requirements/release-requirements.txt commands = {[testenv:docs]commands} python setup.py sdist bdist_wheel