Skip to content

Commit d3c7638

Browse files
authored
refactor: replace verify_interface with isinstance (#467)
* refactor: change verify_interface to isinstance * chore: update test_vector_handlers tox file
1 parent cb63b56 commit d3c7638

8 files changed

+72
-88
lines changed

src/aws_encryption_sdk/internal/crypto/authentication.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from cryptography.hazmat.primitives import hashes, serialization
1919
from cryptography.hazmat.primitives.asymmetric import ec
2020
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
21-
from cryptography.utils import InterfaceNotImplemented, verify_interface
2221

2322
from ...exceptions import NotSupportedError
2423
from .elliptic_curve import (
@@ -47,11 +46,9 @@ def __init__(self, algorithm, key):
4746

4847
def _set_signature_type(self):
4948
"""Ensures that the algorithm signature type is a known type and sets a reference value."""
50-
try:
51-
verify_interface(ec.EllipticCurve, self.algorithm.signing_algorithm_info)
52-
return ec.EllipticCurve
53-
except InterfaceNotImplemented:
49+
if not isinstance(self.algorithm.signing_algorithm_info, type(ec.EllipticCurve)):
5450
raise NotSupportedError("Unsupported signing algorithm info")
51+
return ec.EllipticCurve
5552

5653
def _build_hasher(self):
5754
"""Builds the hasher instance which will calculate the digest of all passed data.

src/aws_encryption_sdk/internal/crypto/elliptic_curve.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@
1818
from cryptography.hazmat.backends import default_backend
1919
from cryptography.hazmat.primitives.asymmetric import ec
2020
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed, decode_dss_signature, encode_dss_signature
21-
from cryptography.utils import InterfaceNotImplemented, int_to_bytes, verify_interface
21+
from cryptography.utils import int_to_bytes
2222

2323
from ...exceptions import NotSupportedError
2424
from ..str_ops import to_bytes
2525

2626
_LOGGER = logging.getLogger(__name__)
2727

28-
2928
# Curve parameter values are included strictly as a temporary measure
3029
# until they can be rolled into the cryptography.io library.
3130
# Expanded values from http://www.secg.org/sec2-v2.pdf
@@ -44,10 +43,10 @@
4443
order=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973,
4544
),
4645
"secp521r1": _ECCCurveParameters(
47-
p=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa pylint: disable=line-too-long
48-
a=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC, # noqa pylint: disable=line-too-long
49-
b=0x0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00, # noqa pylint: disable=line-too-long
50-
order=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409, # noqa pylint: disable=line-too-long
46+
p=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa pylint: disable=line-too-long
47+
a=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC, # noqa pylint: disable=line-too-long
48+
b=0x0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00, # noqa pylint: disable=line-too-long
49+
order=0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409, # noqa pylint: disable=line-too-long
5150
),
5251
}
5352

@@ -182,8 +181,6 @@ def generate_ecc_signing_key(algorithm):
182181
:returns: Generated signing key
183182
:raises NotSupportedError: if signing algorithm is not supported on this platform
184183
"""
185-
try:
186-
verify_interface(ec.EllipticCurve, algorithm.signing_algorithm_info)
187-
return ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend())
188-
except InterfaceNotImplemented:
184+
if not isinstance(algorithm.signing_algorithm_info, type(ec.EllipticCurve)):
189185
raise NotSupportedError("Unsupported signing algorithm info")
186+
return ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend())

test/unit/test_crypto_authentication_signer.py

+31-10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ def patch_default_backend(mocker):
3030
yield aws_encryption_sdk.internal.crypto.authentication.default_backend
3131

3232

33+
@pytest.fixture
34+
def patch_ec(mocker):
35+
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "ec")
36+
yield aws_encryption_sdk.internal.crypto.authentication.ec
37+
38+
3339
@pytest.fixture
3440
def patch_serialization(mocker):
3541
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "serialization")
@@ -71,8 +77,10 @@ def test_f_signer_key_bytes():
7177
assert test.key_bytes() == VALUES["ecc_private_key_prime_private_bytes"]
7278

7379

74-
def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher):
75-
_algorithm = MagicMock()
80+
def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
81+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
82+
_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
83+
7684
signer = Signer.from_key_bytes(algorithm=_algorithm, key_bytes=sentinel.key_bytes)
7785

7886
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
8391
assert signer.key is patch_serialization.load_der_private_key.return_value
8492

8593

86-
def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher):
94+
def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
95+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
96+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
8797
private_key = MagicMock()
88-
signer = Signer(MagicMock(), key=private_key)
98+
signer = Signer(algorithm, key=private_key)
8999

90100
test = signer.key_bytes()
91101

@@ -98,30 +108,41 @@ def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_buil
98108

99109

100110
def test_signer_encoded_public_key(
101-
patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_encode_compressed_point, patch_base64
111+
patch_default_backend,
112+
patch_serialization,
113+
patch_build_hasher,
114+
patch_ecc_encode_compressed_point,
115+
patch_base64,
116+
patch_ec
102117
):
103118
patch_ecc_encode_compressed_point.return_value = sentinel.compressed_point
104119
patch_base64.b64encode.return_value = sentinel.encoded_point
105120
private_key = MagicMock()
106121

107-
signer = Signer(MagicMock(), key=private_key)
122+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
123+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
124+
125+
signer = Signer(algorithm, key=private_key)
108126
test_key = signer.encoded_public_key()
109127

110128
patch_ecc_encode_compressed_point.assert_called_once_with(private_key)
111129
patch_base64.b64encode.assert_called_once_with(sentinel.compressed_point)
112130
assert test_key == sentinel.encoded_point
113131

114132

115-
def test_signer_update(patch_default_backend, patch_serialization, patch_build_hasher):
116-
signer = Signer(MagicMock(), key=MagicMock())
133+
def test_signer_update(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
134+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
135+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
136+
signer = Signer(algorithm, key=MagicMock())
117137
signer.update(sentinel.data)
118138
patch_build_hasher.return_value.update.assert_called_once_with(sentinel.data)
119139

120140

121141
def test_signer_finalize(
122-
patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_static_length_signature
142+
patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_static_length_signature, patch_ec
123143
):
124-
algorithm = MagicMock()
144+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
145+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
125146
private_key = MagicMock()
126147

127148
signer = Signer(algorithm, key=private_key)

test/unit/test_crypto_authentication_verifier.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def test_f_verifier_key_bytes():
8686
def test_verifier_from_encoded_point(
8787
patch_default_backend,
8888
patch_serialization,
89+
patch_ec,
8990
patch_ecc_public_numbers_from_compressed_point,
9091
patch_base64,
9192
patch_build_hasher,
@@ -94,21 +95,24 @@ def test_verifier_from_encoded_point(
9495
mock_point_instance.public_key.return_value = sentinel.public_key
9596
patch_ecc_public_numbers_from_compressed_point.return_value = mock_point_instance
9697
patch_base64.b64decode.return_value = sentinel.compressed_point
97-
algorithm = MagicMock()
98+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
99+
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
98100

99-
verifier = Verifier.from_encoded_point(algorithm=algorithm, encoded_point=sentinel.encoded_point)
101+
verifier = Verifier.from_encoded_point(algorithm=mock_algorithm, encoded_point=sentinel.encoded_point)
100102

101103
patch_base64.b64decode.assert_called_once_with(sentinel.encoded_point)
102-
algorithm.signing_algorithm_info.assert_called_once_with()
104+
mock_algorithm.signing_algorithm_info.assert_called_once_with()
103105
patch_ecc_public_numbers_from_compressed_point.assert_called_once_with(
104-
curve=algorithm.signing_algorithm_info.return_value, compressed_point=sentinel.compressed_point
106+
curve=mock_algorithm.signing_algorithm_info.return_value, compressed_point=sentinel.compressed_point
105107
)
106108
mock_point_instance.public_key.assert_called_once_with(patch_default_backend.return_value)
107109
assert isinstance(verifier, Verifier)
108110

109111

110-
def test_verifier_update(patch_default_backend, patch_serialization, patch_build_hasher):
111-
verifier = Verifier(algorithm=MagicMock(), key=MagicMock())
112+
def test_verifier_update(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
113+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
114+
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
115+
verifier = Verifier(algorithm=mock_algorithm, key=MagicMock())
112116
verifier.update(sentinel.data)
113117
verifier._hasher.update.assert_called_once_with(sentinel.data)
114118

test/unit/test_crypto_elliptic_curve.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
import pytest
1717
from cryptography.hazmat.primitives.asymmetric import ec
18-
from cryptography.utils import InterfaceNotImplemented
1918
from mock import MagicMock, sentinel
2019
from pytest_mock import mocker # noqa pylint: disable=unused-import
2120

@@ -374,22 +373,20 @@ def test_ecc_public_numbers_from_compressed_point(patch_ec, patch_ecc_decode_com
374373
assert test == sentinel.public_numbers_instance
375374

376375

377-
def test_generate_ecc_signing_key_supported(patch_default_backend, patch_ec, patch_verify_interface):
376+
def test_generate_ecc_signing_key_supported(patch_default_backend, patch_ec):
378377
patch_ec.generate_private_key.return_value = sentinel.raw_signing_key
379-
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info)
378+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
380379
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
381380

382381
test_signing_key = generate_ecc_signing_key(algorithm=mock_algorithm)
383382

384-
patch_verify_interface.assert_called_once_with(patch_ec.EllipticCurve, mock_algorithm_info)
385383
patch_ec.generate_private_key.assert_called_once_with(
386384
curve=sentinel.algorithm_info, backend=patch_default_backend.return_value
387385
)
388386
assert test_signing_key is sentinel.raw_signing_key
389387

390388

391-
def test_generate_ecc_signing_key_unsupported(patch_default_backend, patch_ec, patch_verify_interface):
392-
patch_verify_interface.side_effect = InterfaceNotImplemented
389+
def test_generate_ecc_signing_key_unsupported(patch_default_backend, patch_ec):
393390
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info)
394391
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
395392

test/unit/test_crypto_prehashing_authenticator.py

+4-14
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# language governing permissions and limitations under the License.
1313
"""Unit test suite for ``aws_encryption_sdk.internal.crypto._PrehashingAuthenticater``."""
1414
import pytest
15-
from cryptography.utils import InterfaceNotImplemented
1615
from mock import MagicMock, sentinel
1716
from pytest_mock import mocker # noqa pylint: disable=unused-import
1817

@@ -35,12 +34,6 @@ def patch_build_hasher(mocker):
3534
yield _PrehashingAuthenticator._build_hasher
3635

3736

38-
@pytest.fixture
39-
def patch_cryptography_utils_verify_interface(mocker):
40-
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "verify_interface")
41-
yield aws_encryption_sdk.internal.crypto.authentication.verify_interface
42-
43-
4437
@pytest.fixture
4538
def patch_cryptography_ec(mocker):
4639
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "ec")
@@ -71,21 +64,18 @@ def test_init(patch_set_signature_type, patch_build_hasher):
7164

7265

7366
def test_set_signature_type_elliptic_curve(
74-
patch_build_hasher, patch_cryptography_utils_verify_interface, patch_cryptography_ec
67+
patch_build_hasher, patch_cryptography_ec
7568
):
76-
mock_algorithm = MagicMock()
69+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_cryptography_ec.EllipticCurve)
70+
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
7771
test = _PrehashingAuthenticator(algorithm=mock_algorithm, key=sentinel.key)
7872

79-
patch_cryptography_utils_verify_interface.assert_called_once_with(
80-
patch_cryptography_ec.EllipticCurve, mock_algorithm.signing_algorithm_info
81-
)
8273
assert test._signature_type is patch_cryptography_ec.EllipticCurve
8374

8475

8576
def test_set_signature_type_unknown(
86-
patch_build_hasher, patch_cryptography_utils_verify_interface, patch_cryptography_ec
77+
patch_build_hasher, patch_cryptography_ec
8778
):
88-
patch_cryptography_utils_verify_interface.side_effect = InterfaceNotImplemented
8979
with pytest.raises(NotSupportedError) as excinfo:
9080
_PrehashingAuthenticator(algorithm=MagicMock(), key=sentinel.key)
9181

test_vector_handlers/src/pylintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[MESSAGES CONTROL]
1+
[MESSAGE CONTROL]
22
# Disabling messages that we either don't care about for tests or are necessary to break for tests.
33
disable =
44
bad-continuation, # we let black handle this

0 commit comments

Comments
 (0)